所有的 Android 利用程序都有1個包名。包名是裝備上的這個利用程序的唯1標識,也是在谷歌Play商店上的唯1標識。這意味著,1旦你已發布的程序使用了這個包名,
你就永久都沒法改變它;否則會致使你的利用程序被當作是1個全新的利用程序,你之前的利用程序的用戶將不會看到作為更新的安裝包。
在此前Android Gradle 構建系統中,您的利用程序的包名由你的manifest文件的根元素里的package屬性決定:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.my.app"
android:versionCode="1"
android:versionName="1.0" >
但是,這里所定義的包也有第2個目的:它被用來命名你的資源類的包(和解析任何相干的Activity的類名)。在上面的示例中,生成的 R 類將會是com.example.my.app.R
,因此如果您其他包里面的代碼需要援用這些資源,就需要導入com.example.my.app.R。
使用新的 Android Gradle 構建系統,你可以輕松構建多個不同
版本的利用程序;例如,您可以構建1個“free”版本和“pro”版本的利用程序 (通過使用flavors),并且這些不同版本的程序在 Google Play 商店上應當有不同的包,這樣他們可以被單獨安裝和購買,或是同時安裝兩個,等等。一樣,您還可以同時創建“debug”、“alpha”和“beta”版本的利用程序 (使用build types),而這些版本的程序一樣可使用唯1的包名。
同時,您要在代碼中導入的 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"
}
...
像之前1樣,你需要在 Manifest 文件中指定用于代碼的包,就如上面的Andr??oidManifest.xml示例1樣。
這里說到了最關鍵的部份:當你像上面那樣做時,這兩個包是相互獨立的。你能夠完全自由地重構您的代碼――更改用于Activity和Service的內部包,更新你的Manifest里的包,和重構您的導入語句。這都不會影響到你的程序的終究id,這個終究的id總是為你的Gradle文件中指定的applicationId的值。
你可以通過使用以下的 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 (例如1個 flavor 的特定的manifest或1個 buildType 的特定的manifest),該包名是可選的,但如果它被指定了,它必須和主manifest中指定的包完全相同。