Skip to content

Latest commit

 

History

History
89 lines (63 loc) · 4.85 KB

ApplicationId vs PackageName.md

File metadata and controls

89 lines (63 loc) · 4.85 KB

ApplicationId vs PackageName

曾几何时,自从转入Studio阵营后就发现多了个applicationId "com.xx.xxx",虽然知道肯定会有区别,但是我却没有仔细去看,只想着把它和packageName设置成相同即可(原谅我的懒惰- -!)。

直到今天在官网看Gradle使用时,终于忍不住要搞明白它俩的区别。

Android官方文档中有一句是这样描述applicationId的:applicationId : the effective packageName,真是言简意赅,那既然applicationId是有效的包明了,packageName算啥?

所有Android应用都有一个包名。包名在设备上能唯一的标识一个应用,它在Google Play应用商店中也是唯一的。这就意味着一旦你使用一个包名发布应用后,你就永 远不能改变它的包名;如果你改了包名就会导致你的应用被认为是一个新的应用,并且已经使用你之前应用的用户将不会看到作为更新的新应用包。

之前的Android Gradle构建系统中,应用的包名是由你的manifest文件中的根元素中的package属性定义的:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.my.app"
    android:versionCode="1"
    android:versionName="1.0" >

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

伴随着新的Android Gradle构建系统,你可以很简单的为你的应用构建多个不同的版本;例如,你可以同时为你的应用构建一个免费版本和一个专业版(使用flavors),并且他们应该在Google Play商店中有不同的包,这样才能让他们可以被单独安装和购买,同时安装两个,等等。同样的你也可能同时为你的应用构建debug版、alpha版和beta版(使用build types),这些也可以同样使用不同的包名。

在这同时,你在代码中导入的R类必须一直保持一直;在为应用构建不同的版本时.java源文件都不应该发生变化。

因此,我们解耦了package name的两种用法:

  • 在生成的.apk中的manifest文件中使用的最终的包名以及在你的设备和Google Play商店中用来标示你的包名叫做application id的值。
  • 在源代码中指向R类的包名以及在解析任何与activity/service注册相关的包名继续叫做package name

可以在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文件中指定你在代码中使用的package name,像上面AndroidManifest.xml的例子。
下面进入关键部分了:当你按照上面的方式做完后,这两个包就是相互独立的了。你现在可以很简单的重构你的代码-通过修改Manifest中的包名来修改在你的activitiseservices中使用的包和在重构你在代码中的引用声明。这不会影响你应用的最终id,也就是在Gradle文件中的applicationId

你可以通过以下Gradle DSL方法为应用的flavorsbuild types指定不同的applicationId:

app/buid.gradle:

productFlavors {
    pro {
        applicationId = "com.example.my.pkg.pro"
    }
    free {
        applicationId = "com.example.my.pkg.free"
    }
}

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

(在Android Studio中你也可以通过图形化的Project Structure的对话框来更改上面所有的配置)

注意:为了兼容性,如果你在build.gradle文件中没有定义applicationId ,那applicationId就是与AndroidManifest.xml中配置的包名相同的默认值。在这种情况下,这两者显然脱不了干系,如果你试图重构代码中的包就将会导致同时会改变你应用程序的id!在Android Studio中新创建的项目都是同时指定他们俩。

注意2:package name必须在默认的AndroidManifest.xml文件中指定。如果有多个manifest文件(例如对每个flavor制定一个manifest或者每个build type制定一个manifest)时,package name是可选的,但是如果你指定的话,它必须与主manifest中指定的pakcage相同。