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