每个Android应用程式都有一个独特的应用程式ID,看起来像是Java包名,例如com.example.myapp。 此ID可在设备和Google Play商店中唯一标识您的应用。 如果您要上传新版应用程式,应用程式ID(以及您签署的凭证)必须与原本的APK相同 - 如果您变更应用程式ID,Google Play商店会将APK视为完全不同的 app。 因此,一旦发布应用程序,您就不应更改应用程序ID。
应用程序ID是使用模块build.gradle
文件中的applicationId
属性定义的,如下所示:
android {
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
...
}
当您在Android Studio中创建新项目时,applicationId
与您在安装过程中选择的Java样式的包名完全匹配。 但是,应用程序ID和包名称在这一点之外是彼此独立的。 您可以更改代码的包名(代码命名空间),它不会影响应用程序ID,反之亦然(但是,一旦发布应用程序,您就不应该更改应用程序ID)。 但是,更改包名还有其他一些您应该注意的事项,请参阅有关修改包名的部分。
虽然应用程序ID看起来像一个传统的Java程序包名称,但应用程序ID的命名规则有一些限制:
- 它必须至少有两个段(一个或多个点)。
- 每个段必须以字母开头。
- 所有字符必须为字母数字或下划线[a-zA-Z0-9_]。
应用程序ID以前直接绑定到您的代码的包名称; 因此一些Android API在其方法名称和参数名称中使用术语“包名称”,但这实际上是您的应用程序ID。 例如,
Context.getPackageName()
方法返回您的应用程序ID。 没有必要在应用代码之外分享代码的真实包名。警告:如果您正在使用WebView,请考虑在您的应用程序ID中使用您的程序包名称作为前缀; 否则您可能会遇到问题211768中所述的问题。
构建变量更改应用程序ID
当为您的应用程序构建APK时,构建工具使用build.gradle
文件中的defaultConfig
块中定义的应用程序ID来标记APK(如下所示)。 但是,如果您想要创建不同版本的应用以在Google Play商店中显示为单独的商家信息(例如“免费”和“专业版”),则需要使用构建变量创建各自具有不同应用ID的独立版本。
在这种情况下,每个构建变体应定义为单独的产品风格。 对于the productFlavors {}
块中的每个flavor,您可以重新定义applicationId
属性,或者您可以使用applicationIdSuffix
属性在默认应用程序ID基础上附加一段,如下所示:
android {
defaultConfig {
applicationId "com.example.myapp"
}
productFlavors {
free {
applicationIdSuffix ".free"
}
pro {
applicationIdSuffix ".pro"
}
}
}
这样,“免费”产品的应用程序ID为“com.example.myapp.free”。
您还可以使用applicationIdSuffix
根据您的构建类型附加段,如下所示:
android {
...
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
}
因为Gradle在应用构建配置上,buildTypes
在productFlavors
之后,所以“免费调试”的应用程序ID现在是“com.example.myapp.free.debug”。 当您希望在同一设备上同时创建调试和发布版本时,这是非常有用的,因为没有两个APK可以具有相同的应用程序ID。
请注意,具有不同应用程式ID的APK会被视为Google Play商店中的不同应用程式。 因此,如果您想使用相同的应用程式清单来分发多个APK,而每个APK都指定不同的配置(例如API等级),则必须为每个构建版本使用相同的应用程序ID,但为每个APK提供不同的versionCode。 有关详细信息,请阅读有关Multiple APK支持。
警告:为了与以前的SDK工具兼容,如果未在
build.gradle
文件中定义applicationId
属性,构建工具将使用AndroidManifest.xml
文件中的包名称作为应用程序ID。 在这种情况下,重构包名称也会更改应用程序ID。提示:如果您需要在清单文件中引用应用程序ID,则可以在任何清单属性中使用
${applicationId}
占位符。 在构建期间,Gradle将此标记重新放置为实际应用程序ID。 有关更多信息,请参阅将构建变量注入到清单。
更改应用程序ID以进行测试
默认情况下,构建工具会使用指定构建版本的应用程序ID(附加.test)将应用程序ID应用到您的instrumentation test APK。 例如,com.example.myapp.free
构建测试APK版本的应用程序ID为com.example.myapp.free.test
。
虽然没有必要,但您可以通过在defaultConfig
或 productFlavor
中的testApplicationId
来更改应用程序ID。
注意:为了避免与测试中的应用程序发生名称冲突,构建工具会为测试APK生成R类,并使用基于测试应用程序ID的命名空间,而不是在清单文件中定义的包名称。
更改包名称
虽然默认情况下项目的程序包名称与应用程序ID相匹配,但您可以更改它。 但是,如果要更改程序包名称,请注意程序包名称(由项目目录结构定义)应始终与AndroidManifest.xml文件中的程序包属性相匹配,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0" >
Android构建工具使用package属性来做两件事情:
- 它将此名称应用为应用程序生成的R.java类的命名空间。
示例:使用上面的清单,R类将是com.example.myapp.R。 - 它用来解析在清单文件中声明的任何相关类名。
示例:使用上面的清单,声明为<activity android:name=".MainActivity">
的活动被解析为com.example.myapp.MainActivity
。
因此,package属性中的名称应该始终与您的项目的基本包名称保持activities和其他应用程序代码。 当然,你可以在项目中有子包,但是这些文件必须使用package属性中的命名空间导入R.java类,并且在清单中声明的任何应用程序组件必须添加缺少的子包名称(或使用完全限定包名称)。
如果你想完全重构你的包名,一定要更新包属性。 只要您使用Android Studio的工具重命名和重构您的软件包,这些工具就会自动保持同步。 (如果它们不保持同步,您的应用代码无法解析R类,因为它不再位于同一个包中,并且清单将无法识别您的活动或其他组件。)
您必须始终在项目的主AndroidManifest.xml
文件中指定package
属性。 如果您有其他清单文件(例如对于产品风格或构建类型),请注意,由最高优先级清单文件提供的软件包名称始终用于最终合并的清单。 有关更多信息,请参阅合并多个清单文件。
还有一件事要知道:虽然清单中的
package
和GradleapplicationId
可能有不同的名称,但构建工具会在构建结束时将应用程序ID复制到APK的最终清单文件中。 所以如果你在构建之后检查你的AndroidManifest.xml
文件,不要惊讶,package
属性已经改变。 软件package
属性是Google Play商店和Android平台实际用来识别您的应用的地方; 所以一旦构建使用原始值(命名空间R类并解析清单类名称),它将丢弃该值并将其替换为应用程序ID。