首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >什么时候在Android中使用ComponentName的构造函数?

什么时候在Android中使用ComponentName的构造函数?
EN

Stack Overflow用户
提问于 2011-02-14 02:02:39
回答 3查看 28.7K关注 0票数 33

我对安卓中的ComponentName类有点困惑。

有不同的方法可以获取组件名称对象,但我不知道何时使用哪种方法……为什么!

示例:

de.zordid.sampleapp

  • but微件提供程序类为de.zordid.sampleapp.widget.WidgetProvider

  • 应用程序包

使用

代码语言:javascript
复制
ComponentName cn = new ComponentName("de.zordid.sampleapp.widget",
    "WidgetProvider");

我得到了这个组件信息:ComponentInfo{de.zordid.sampleapp.widget/WidgetProvider},但是我不能使用它--这个组件是未知的!但是JavaDoc说我应该提供包和包中的类-这就是我所做的,不是吗?

使用

代码语言:javascript
复制
ComponentName cn = new ComponentName(context, WidgetProvider.class);

生成ComponentInfo{de.zordid.sampleapp/de.zordid.sampleapp.widget.WidgetProvider} -而且工作得很好!

甚至还有另一种方法来获取ComponentName -通过上下文和字符串。哪一个应该在何时何地使用?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-14 02:43:39

接受两个StringComponentName构造函数可以用来引用另一个应用程序中的组件。但是,第一个参数不是类的包名;而是应用程序的包名-应用程序的AndroidManifest.xmlmanifest元素的package属性。所以你的第一个例子应该是

代码语言:javascript
复制
ComponentName cn = new ComponentName("de.zordid.sampleapp",
    "de.zordid.sampleapp.widget.WidgetProvider");

该构造函数当然可以用来引用您自己的应用程序中的组件,但是既然您已经从自己的应用程序中获得了一个Context,那么您最好使用它并使用其他构造函数之一。在我看来,只要可用,参加Class考试的人应该是首选的。如果出于某种原因只动态地知道类,那么可以使用接受String的方法;在这种情况下,它应该采用上面的完全限定类名。

票数 49
EN

Stack Overflow用户

发布于 2016-06-19 18:42:28

关于优先选择对象而不是字符串,Robert Tupelo-Schneck的回答是正确的,下面是我的看法。

  • 要引用您自己的组件,请使用:

WidgetProvider.class);

  • To (getApplicationContext(),new ComponentName指的是您自己的应用程序中一些动态引用的组件,请使用:

//取值/字符串.xml: de.zordid.sampleapp.widget.WidgetProvider String fqcn = getResources().getString(R.string.provider);new ComponentName(getApplicationContext(),fqcn);

当你想使用Android的资源限定符来决定使用哪个组件时,这是很有用的,你可以覆盖values-*/strings.xml.

  • To中的默认字符串引用另一个应用程序的组件,使用:

context.getPackageManager().getPackageInfo("com.other.app",componentFlags = GET_ACTIVITIES | GET_PROVIDERS | GET_RECEIVERS | GET_SERVICES;PackageInfo otherApp = int componentFlags);ComponentInfo info = otherApp.activitiesi;//或者提供者/接收者/...新建ComponentName(info.packageName,info.name);

关于.Names和<manifest package="

这里可能有一些混淆,因为我认为从历史上看,罗伯特的说法是正确的:

它是应用程序的包名-该应用程序的AndroidManifest.xml中清单元素的包属性

但现在不是了。自从引入了新的Gradle构建系统后,这里就出现了some changes

如果您在build.gradle中指定了一个android.defaultConfig.applicationId,它将是应用程序包的名称,那么在构建应用程序时,清单中的package属性是另一回事。现在,ComponentName的第一个参数引用了applicationId + applicationIdSuffix。棘手的是,在最终的清单合并和打包之后,APK将拥有<manifest package=applicationId + applicationIdSuffix,所有的.Names都将扩展为FQCN。

学习名称解析的示例应用程序

这是一个基于我的一个应用程序结构的示例结构。考虑一下名为“app”的假想应用程序中的以下类:

  • net.twisterrob.app.android.App
  • net.twisterrob.app.android.GlideSetup
  • net.twisterrob.app.android.subpackage.SearchResultsActivity
  • net.twisterrob.app.android.subpackage.Activity
  • net.twisterrob.app.android.content.AppProvider

在应用程序的服务器端后端和/或一些共享模型类上:

  • net.twisterrob.app.data.*
  • net.twisterrob.app.backend.*
  • net.twisterrob.app.web.*

在我的Android助手库中:

  • net.twisterrob.android.activity.AboutActivity

其他库:

  • android.support.v4.content.FileProvider

这样,所有内容都在net.twisterrob.app中命名空间。android应用程序只是它自己的子包中整体的一部分。

AndroidManifest.xml (省略不相关的部分)

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="net.twisterrob.app.android">
    <!--
    `package` above defines the base package for .Names
    to simplify reading/writing the manifest.
    Notice that it's different than the `applicationId` in build.gradle
    and can be independently changed in case you want to refactor your packages.
    This way you can still publish the same app with the same name.
    -->

    <!-- Will be expanded to net.twisterrob.app.android.App in the manifest merging phase. -->
    <application android:name=".App">
        <!-- meta-data needs FQCNs because the merger can't know if you want to expand them or not.
             Also notice that name and value both can contain class names, depending on what you use. -->
        <meta-data android:name="net.twisterrob.app.android.GlideSetup" android:value="GlideModule" />
        <meta-data android:name="android.app.default_searchable" android:value="net.twisterrob.app.android.subpackage.SearchResultsActivity" />
        <!-- Will be expanded to net.twisterrob.app.android.subpackage.Activity in the manifest merging phase. -->
        <activity android:name=".subpackage.Activity" />
        <!-- Needs full qualification because it's not under the package defined on manifest element. -->
        <activity android:name="net.twisterrob.android.activity.AboutActivity" />
        <!-- Will be expanded to net.twisterrob.app.android.content.AppProvider in the manifest merging phase. -->
        <provider android:name=".content.AppProvider" android:authorities="${applicationId}" />
        <!-- Needs full qualification because it's not under the package defined on manifest element. -->
        <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.share" />
    </application>
    <!-- ${applicationId} will be replaced with what's defined in `build.gradle` -->
</manifest>

build.gradle

代码语言:javascript
复制
android {
    defaultConfig {
        // this is what will be used when you upload it to the Play Store
        applicationId 'net.twisterrob.app'
    }
    buildTypes {
        debug {
            // The neatest trick ever!
            // Released application: net.twisterrob.app
            // IDE built debug application: net.twisterrob.app.debug
            // This will allow you to have your installed released version
            // and sideloaded debug application at the same time working independently.
            // All the ContentProvider authorities within a system must have a unique name 
            // so using ${applicationId} as authority will result in having two different content providers.
            applicationIdSuffix '.debug'
        }
    }
}

要查看所有合并后的最终清单会是什么样子,请打开build\intermediates\manifests\full\debug\AndroidManifest.xml

票数 8
EN

Stack Overflow用户

发布于 2012-02-14 04:35:58

或者您可以像这样在BroadcastReceiver中使用:

代码语言:javascript
复制
ComponentName smsReceiver = new ComponentName(this, SMSReceiver.class);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4985859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档