Android官方技术文档翻译——ApplicationId 与 PackageName

本文深入探讨了Android应用中的ApplicationId和PackageName的区别与用法,解释了为何需要解耦这两种标识符,以及如何在构建不同版本的应用时灵活管理它们。重点介绍了如何在Gradle构建系统中设置和修改ApplicationId,以及如何使用flavors和buildtypes来创建和管理具有不同包名的应用程序。此外,文章还强调了保持代码中R类引用的稳定性的重要性。

本文译自androd官方技术文档《ApplicationId versus PackageName》,原文地址:http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename。

本文地址:http://blog.csdn.net/maosidiaoxian/article/details/41719357。转载请注明出处。翻译如有错讹,敬请指正。


ApplicationId 与 PackageName

所有的 Android 应用程序都有一个包名。包名是设备上的这个应用程序的唯一标识,也是在谷歌Play商店上的唯一标识。这意味着,一旦你已发布的程序使用了这个包名, 你就永远都无法改变它;如果修改了就会导致你的应用程序被当作是一个全新的应用程序,你之前的应用程序的用户也不能更新到使用了新的包名的安装包。

在此前的 Android Gradle 构建系统中,您的应用程序的包名由你的manifest文件的根元素里的package属性决定:

AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.my.app"
    android:versionCode="1"
    android:versionName="1.0" >

然而,这里所定义的包也有第二个目的:它被用来命名你的资源类的包(以及解析任何相关的Activity的类名)。在上面的示例中,生成的 R 类将会是com.example.my.app.R,因此如果您其他包里面的代码需要引用这些资源,就需要导入com.example.my.app.R

使用新的 Android Gradle 构建系统,你可以轻松构建多个不同版本的应用程序;例如,您可以构建一个“free”版本和“pro”版本的应用程序 (通过使用flavors),并且这些不同版本的程序在 Google Play 商店上应该有不同的包,这样他们可以被单独安装和购买,或者是同时安装两个,等等。同样,您还可以同时创建“debug”、“alpha”和“beta”版本的应用程序 (使用build types),而这些版本的程序同样可以使用唯一的包名。

同时,您想要在代码中导入的 R 类必须在这段时间内保持不变 ;在您正在构建您的应用程序的不同版本时您的.java 源文件不应该被更改。

因此,我们解耦了包名称的两种用法:
  • 最终的方案是,在您生成的.apk 的manifest 中,并且用于在你的设备和 Google Play 商店来标识你的应用的包,叫做“application id”。
  • 用于在源代码中来引用您的R类的,并且是解析任何相关的Activity/Service 注册的包,继续被称为“package”。
你可以在你 gradle 文件中,指定application id,如下所示:

app/build.gradle:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 19
    buildToolsVersion "19.1"

    defaultConfig {
        applicationId "com.example.my.app"
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    ...

像以前一样,你需要在 Manifest 文件中指定用于代码的包,就如上面的Andr​​oidManifest.xml示例一样。

这里说到了最关键的部分:当你像上面那样做时,这两个包是互相独立的。你能够完全自由地重构您的代码——更改用于Activity和Service的内部包,更新你的Manifest里的包,和重构您的导入语句。这都不会影响到你的程序的最终id,这个最终的id的值总是为你的Gradle文件中指定的applicationId的值。(笔者注:packageName在代码中使用,通常在AndroidManifest.xml中指定,applicationId则只是用于程序的标识,通常在build.gradle中指定。这样有一个好处,假如你想发布一个免费版,一个收费版,你只需要在build.gradle中把applicationId后面加上免费版的后缀包名(如".free"),收费版加上收费版的后缀即可,而不需要修改你的其他代码。)

你可以通过使用以下的 Gradle DSL 方法,为不同的flavors和构建类型修改您的应用程序的 applicationId:

app/build.gradle:
    productFlavors {
        pro {
            applicationId = "com.example.my.pkg.pro"
        }
        free {
            applicationId = "com.example.my.pkg.free"
        }
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
    ....

(在 Android Studio 中,您也可以在项目结构对话框中图形化地进行这些配置。)

注意: 出于兼容性原因,如果您没有在您的 build.gradle 文件中定义 applicationId,这个applicationId 将默认为 AndroidManifest.xml 中所指定的相同的值。在这种情况下,这两个显然未解耦,并且如果你试图重构您的代码也将会意外地更改您的应用程序的 id !在 Android Studio 中,新建的项目始终会指定这两个值。

注 2: 包名称必须始终在默认 AndroidManifest.xml 文件中指定。如果您有多个manifest (例如一个 flavor 的特定的manifest或一个 buildType 的特定的manifest),该包名是可选的,但如果它被指定了,它必须和主manifest中指定的包完全相同。


### 三级标题:Android 中 `applicationId` `AndroidManifest.xml` 中 `package` 的关系 在 Android 应用开发中,`applicationId` `AndroidManifest.xml` 中的 `package` 是两个不同的概念,但在某些情况下需要保持一致以确保应用正常运行。 `applicationId` 是应用在设备和 Google Play 上的唯一标识,用于区分不同的应用。它通常在 `build.gradle` 文件中定义,例如: ```gradle android { defaultConfig { applicationId "com.example.myapp" minSdkVersion 21 targetSdkVersion 30 versionCode 1 versionName "1.0" } } ``` `AndroidManifest.xml` 中的 `package` 属性则用于在源码中引用资源类(如 `R` 类)以及解析注册相关的组件(如 `Activity` 和 `Service`),其概念 Java 的包名一致。它通常定义在 `AndroidManifest.xml` 文件中,例如: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp"> ``` 在大多数情况下,`applicationId` 和 `package` 是一致的,特别是在使用 Android Studio 创建新项目时,默认会将两者设置为相同值。虽然它们可以不同,但在某些场景下需要注意一致性问题。例如,当一个应用包含多个包名时,`AndroidManifest.xml` 中的 `package` 必须应用入口(即包含 `MAIN` + `LAUNCHER` 的 `intent-filter` 的 `Activity`)所在的包名一致,否则可能导致运行时无法正确加载主 `Activity`[^1]。 此外,如果一个应用包含多个 `AndroidManifest.xml` 文件(如针对不同构建变体的清单文件),则主清单中的 `package` 必须所有其他清单文件中的 `package` 保持一致,否则会导致构建失败或安装冲突[^2]。 ### 三级标题:何时需要保持一致性 当应用的 `AndroidManifest.xml` 中的 `package` `applicationId` 不一致时,可能会出现资源引用错误或组件注册失败的情况。例如,如果 `package` 被错误地设置为 `com.example.wrongpackage`,而实际 Java 文件位于 `com.example.myapp` 包下,则系统无法正确解析 `R` 类和组件路径,从而导致编译或运行时错误。 因此,为了确保应用能够正确构建和运行,建议在大多数情况下保持 `applicationId` 和 `AndroidManifest.xml` 中的 `package` 一致。如果不一致,则必须确保所有组件的路径和资源引用都 `package` 值匹配,这会增加维护复杂性[^3]。 ### 三级标题:构建安装时的影响 在构建过程中,Gradle 会使用 `applicationId` 作为最终 APK 的唯一标识符,而 `package` 仅用于源码级别的引用和组件注册。因此,即使 `applicationId` `package` 不同,只要 `package` 正确指向源码结构,并且所有组件路径一致,应用仍然可以构建成功[^4]。 然而,在安装过程中,如果多个应用使用相同的 `applicationId`,即使它们的 `package` 不同,也会导致安装失败,提示“现有应用冲突”。这是因为 Android 系统使用 `applicationId` 作为应用的唯一标识符,不允许重复[^4]。
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值