【问题标题】:When to use application ID or package name a.k.a. is the PackageManager#getLaunchIntentForPackage method name incorrect?何时使用应用程序 ID 或包名称,也就是 PackageManager#getLaunchIntentForPackage 方法名称不正确?
【发布时间】:2019-03-18 13:52:37
【问题描述】:

什么时候使用“应用程序 ID”或“包”?

(或者是“包名”?)

我在实际情况下的困惑:

从一个应用程序切换到另一个应用程序的一种方法是获取应用程序的启动意图,这可以使用(给定一些context)来完成:

PackageManager manager = context.getPackageManager();
Intent intent = manager.getLaunchIntentForPackage(packageName);

请注意,参数的名称称为packageName,甚至方法名称也提到了“包”。但是,这不是包名!这是我们应该在这里使用的应用程序 ID!

例如,如果我有一个调试构建类型,而不是发布应用程序 ID com.example 有一个调试后缀,例如它是com.example.debug,我必须使用"com.example.debug" 作为getLaunchIntentForPackage 的参数。但是应用程序的包命名空间保持不变(by default):仍然是com.example!如果我没有安装我的非调试应用程序,getLaunchIntentForPackage 方法将返回 null,因为未安装应用程序 ID com.example。

那么我在看什么?我认为com.example 是我的包名,com.example.debug 是我的应用程序 ID。但是为什么PackageManager#getLaunchIntentForPackage方法会提到'package'和'package name',而认为它应该提到'application ID'呢?

这只是 Android SDK 中一个错误命名的方法,还是我误解了什么?

我的问题基于以下信息。

从application IDs 的文档中,我引用:

每个 Android 应用都有一个唯一的应用 ID,类似于 Java 包名称,例如 com.example.myapp。此 ID 在设备上和 Google Play 商店中唯一标识您的应用。如果您要上传应用的新版本,应用 ID(以及 certificate you sign it with)必须与原始 APK 相同——如果您更改应用 ID,Google Play 商店会将 APK 视为完全不同的应用。因此,一旦您发布了您的应用,您永远不应更改应用 ID。

[...]

当您在 Android Studio 中创建新项目时,applicationId 与您在设置过程中选择的 Java 样式包名称完全匹配。但是,应用程序 ID 和包名称在此之后相互独立。您可以更改代码的包名称(您的代码命名空间),它不会影响应用程序 ID,反之亦然(但同样,一旦发布应用程序,您不应更改应用程序 ID)。但是,更改包名还有其他后果您应该注意,因此请参阅有关 modifying the package name 的部分。

因此,应用 ID 可以在 Play 商店中唯一标识您的应用。包名是应用程序代码库中子包和类的命名空间。到目前为止一切顺利,我明白这一点。

但是,在本文档页面的末尾,我们有以下更令人困惑的亮点:

还有一点需要了解:虽然您可能有不同的清单名称 package 和 Gradle applicationId,但构建工具会将应用程序 ID 复制到您的 APK 的最终清单文件中构建结束。因此,如果您在构建后检查您的AndroidManifest.xml 文件,请不要对package 属性已更改感到惊讶。 package 属性是 Google Play 商店和 Android 平台实际用于识别您的应用的位置;因此,一旦构建使用了原始值(将 R 类命名为命名空间并解析清单类名称),它就会丢弃该值并将其替换为应用程序 ID。

所以这里我们在一页上有多个矛盾!

  1. Google Play 通过应用 ID 和包来识别应用。
  2. 清单的程序包名称可能与应用程序 ID 不同,而在编译时,程序包会被构建工具的应用程序 ID 覆盖。

从这个亮点来看,至少关于应用程序覆盖包名的构建工具的说法似乎是不正确的,因为:

在应用程序com.example.debug 中为活动com.example.MainActivity 创建意图时,我必须将com.example.debug 指定为应用程序ID,将com.example.MainActivity 指定为组件名称。在运行时,组件名并没有将其包名更改为应用程序ID,因此构建工具似乎没有更改包命名空间?

我希望...

...有人可以通过各种示例创建一个很好的答案,这些示例显示应用程序 ID 和包(名称)何时相同,或者何时不同,以及 Android 系统和 Google Play 实际使用哪个。还请考虑一个具有库依赖关系的示例:据我了解,库的包命名空间没有改变,但它使用您的应用程序 ID 运行,对吗?

【问题讨论】:

    标签: android android-intent android-package-managers


    【解决方案1】:

    <manifest> 中的android:package 属性就是我们这里要讨论的内容。它曾经被称为“包名”,在一些旧文档中仍然被称为“包名”。它不是 Java 包名,尽管它看起来像一个,并且与源代码中的 Java 包名无关。

    最近此属性被称为“应用程序 ID”,尤其是在与 Firebase、Play 商店等相关的文档中。

    这是同样的事情。 “包名”是“应用程序 ID”。

    参考https://developer.android.com/guide/topics/manifest/manifest-element.html#package

    注意:

    有一个地方可能会让事情变得混乱,那就是清单中组件名称的简写符号。例如:

        <activity
                android:name=".ui.activities.MainActivity">
        </activity>
    

    在这种情况下,android:name 属性指定“Activity 的完全限定 Java 类名”。但是,如果名称以句点开头(如本例所示),则应用程序的“包名称”(来自 &lt;manifest&gt; 标记的 android:package 属性)将添加到类名称之前,以形成完全限定的 Java Activity 的类名。

    如果您遇到 android:package 属性因不同的构建变体而更改的情况(如在您的示例中,在包名称中使用 debug),您不应在清单!您应该始终使用完全限定名称,如下所示:

        <activity
                android:name="com.mycompany.mypackage.ui.activities.MainActivity">
        </activity>
    

    【讨论】:

    • 所以,为了尽量减少混淆,我应该在清单中谈论名称/ID 时使用“应用程序 ID”?确实,很令人困惑的是,以简写形式添加的包名确实有所不同,但同时&lt;manifest&gt; 中的android:package 属性默认等于实际的Java 包名。
    • 随心所欲。您只需要了解应用程序的“包名”不是源代码的“Java 包名”。默认情况下,它们是相同的,但不一定是。
    猜你喜欢
    • 2016-04-18
    • 2014-02-12
    • 1970-01-01
    • 2023-04-08
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多