配置应用模块

本页介绍了您可能希望切换的模块级 build.gradle 文件中的实用应用设置。除了简要介绍 build.gradle 文件中设置的重要属性之外,我们还介绍了如何执行以下操作:

  • 更改不同 build 配置的应用 ID。
  • 独立于应用 ID 安全地调整命名空间。

设置应用 ID

每个 Android 应用均有一个唯一的应用 ID,像 Java 软件包名称一样,例如 com.example.myapp。此 ID 可以作为您的应用在设备上和 Google Play 商店中的唯一标识。发布应用后,绝不应更改应用 ID。如果您要上传新版本的应用,应用 ID(以及用于为其签名的证书)必须与最初发布时相同。如果您更改了应用 ID,Google Play 商店会将上传的应用视为完全不同的应用。

应用 ID 由模块的 build.gradle 文件中的 applicationId 属性定义,如下所示:

Groovy

android {
    defaultConfig {
        applicationId "com.example.myapp"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    ...
}

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 15
        targetSdk = 24
        versionCode = 1
        versionName = "1.0"
    }
    ...
}

虽然应用 ID 看起来就像传统的 Java 软件包名称(代码的命名空间),但应用 ID 的命名规则限制性更强一些:

  • 必须至少包含两段(一个或多个圆点)。
  • 每段必须以字母开头。
  • 所有字符必须为字母数字或下划线 [a-zA-Z0-9_]。

当您在 Android Studio 中创建新项目时,系统会自动为 applicationId 分配您在设置期间选择的 Java 样式软件包名称。在技术上讲,从此以后您可以单独切换这两个属性,但我们不建议这样做。

我们建议您在设置应用 ID 时遵循以下做法:

  • 让应用 ID 与命名空间保持一致。这两个属性之间的区别可能有点令人困惑,但如果您让二者保持一致,就没有什么可担心的了。
  • 发布应用后,请勿更改应用 ID。如果您更改此 ID,Google Play 商店会将后续上传的版本视为新应用。
  • 明确定义应用 ID。如果未使用 applicationId 属性明确定义应用 ID,系统会自动采用与命名空间相同的值作为应用 ID。这意味着,一旦您更改了命名空间,应用 ID 也会随之更改,而这通常是没有必要的。

注意:应用 ID 过去直接关联到代码的软件包名称;所以,有些 Android API 会在其方法名称和参数名称中使用“package name”一词,但这实际上是您的应用 ID。例如,Context.getPackageName() 方法会返回您的应用 ID。无论何时都不需要在应用代码以外分享代码的真实软件包名称。

注意:如果您使用的是 WebView,不妨考虑在您的应用 ID 中将软件包名称用作前缀;否则,您可能会遇到如问题 211768 中所述的问题。

更改用于测试的应用 ID

默认情况下,构建工具会将应用 ID 应用到您的插桩测试 APK,该 APK 将应用 ID 用于给定的 build 变体,同时追加 .test。例如,com.example.myapp.free build 变体的测试 APK 的应用 ID 为 com.example.myapp.free.test

您可以通过在 defaultConfigproductFlavor 块中定义 testApplicationId 属性来更改应用 ID,不过应该没有必要这样做。

设置命名空间

每个 Android 模块都有一个命名空间,此命名空间用作其生成的 RBuildConfig 类的 Java 软件包名称。

命名空间由模块的 build.gradle 文件中的 namespace 属性定义,如以下代码段所示。namespace 最初会设为您在创建项目时选择的 Java 样式软件包名称。

android {
    namespace 'com.example.myapp'
    ...
}

在将应用构建为最终应用软件包 (APK) 时,Android 构建工具使用命名空间来发挥两种作用:

  • 它们将此名称用作应用生成的 R.java 类(用于访问应用资源)的命名空间。

    示例:在前面的 build 文件中,在 com.example.myapp.R 处创建了 R 类。

  • 它们会使用此名称解析清单文件中声明的任何相关类名。

    示例:在前面的 build 文件中,被声明为 <activity android:name=".MainActivity"> 的 activity 将解析为 com.example.myapp.MainActivity

因此,您为 build.gradle 文件的 namespace 属性设置的名称应始终与项目的基础软件包名称匹配,基础软件包中保存着您的 activity 及其他应用代码。当然,您的项目可以包含其他子软件包,但这些文件必须使用 namespace 属性中的命名空间导入 R.java 类。

为简化工作流,我们还建议您让命名空间与应用 ID 保持一致(与二者的默认设置一样)。

更改命名空间

我们强烈建议您让命名空间和应用 ID 保持一致(与二者的默认设置一样)。但是,如果您要重新整理代码,或要避免命名空间发生冲突,有时可能需要更改命名空间。在这些情况下,您可以抛开应用 ID,单独更改命名空间(通过更新模块 build.gradle 文件中的 namespace 属性)。在此之前,请确保您明确定义了应用 ID,这样一来,更改命名空间就不会导致应用 ID 发生更改。如需详细了解命名空间对应用 ID 的影响,请参阅设置应用 ID

如果 namespace 的名称与 Gradle applicationId 的名称不一致,请注意,构建工具会在构建结束时将应用 ID 复制到应用的最终清单文件中。所以,如果您在构建后检查 AndroidManifest.xml 文件,发现 package 属性已设为应用 ID 就不足为奇了。实际上,Google Play 商店和 Android 平台会查看合并后的清单的 package 属性以识别您的应用。

更改命名空间以进行测试

androidTesttest 源代码集的默认命名空间是主命名空间,并且末尾添加了 .test。例如,如果 build.gradle 文件中的 namespace 属性为 com.example.myapp,则测试命名空间默认设置为 com.example.myapp.test。如需更改命名空间以进行测试,请使用 testNamespace 属性,如以下代码段所示:

android {
    namespace 'com.example.myapp'
    testNamespace 'com.example.mytestapp'
    ...
}

注意:请勿将 testNamespacenamespace 设置为相同的值,否则会出现命名空间冲突。

如需详细了解测试,请参阅在 Android 平台上测试应用