Android Package Name vs. Application ID

簡評:最熟悉的地方也會有大學(xué)問。

對于 Android 開發(fā)者來說,Package Name 應(yīng)當(dāng)再熟悉不過了,或許有些同學(xué)還注意到了 App 的 build.gradle 中有一個 applicationId,它的值通常都和包名一致,但其實(shí)二者是存在區(qū)別的。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  package="com.stylingandroid.packagename">
 
  ...
</manifest>

可以看到這里有一個包名:com.stylingandroid.packagename,而我們這里在 build.gradle 中為 applicationId 加上 .release 和 .debug 兩個不同的后綴:

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"
    defaultConfig {
        applicationId "com.stylingandroid.packagename"
        minSdkVersion 23
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            applicationIdSuffix ".release"
        }
        debug {
            applicationIdSuffix ".debug"
        }
    }
}

我們比較打包出來兩個 APK 的 Manifest 文件,可以觀察下其中 package 的值:



可以發(fā)現(xiàn)應(yīng)用最終的包名其實(shí)是由 applicationId 決定的,而之前 Manifest 中的 package 值主要是做兩件事:

  • 指明類的路徑。比如我們在 manifest 文件中聲明<activity android:name=".MainActivity">,實(shí)際會被解析為 com.stylingandroid.packagename.MainActivity
  • 指明 R.java 文件的路徑,對于本文的例子來說就是 com.stylingandroid.packagename.R

這些在官方文檔中都有講解,主要需要注意的是文檔的最后一段:

Although you may have a different name for the manifest package and the Gradle applicationId, the build tools copy the application ID into your APK’s final manifest file at the end of the build

注意文檔中所說的,Android 是在程序編譯的 最后 才將 application ID 拷貝進(jìn) APK 的 manifest 文件的。

如果你像上面那樣在 buildTypes 中修改了 applicationId 值,那么在代碼中想要獲取到應(yīng)用包名就需要注意,看看下面的代碼:

public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
 
       TextView packageNameTextView = (TextView) findViewById(R.id.package_name);
       TextView applicationIdTextView = (TextView) findViewById(R.id.application_id);
 
       packageNameTextView.setText(getString(R.string.package_name, BuildConfig.class.getPackage().toString()));
       applicationIdTextView.setText(getString(R.string.application_id, BuildConfig.APPLICATION_ID));
    }
}

結(jié)果分別為:

  • Package Name: package com.stylingandroid.packagename
  • Application ID: com.stylingandroid.packagename.debug

那為什么 Android 要在編譯的最后才將 application ID 拷貝進(jìn) manifest 文件中呢?

理由很簡單,如果 BuildConfig.java 和 R.java 文件使用了 applicationId 而不是 package name,編譯的時候路徑會出錯。

原文:Package Name vs. Application ID

日報延伸閱讀

歡迎關(guān)注

  • 知乎專欄「極光日報」,每天為 Makers 導(dǎo)讀三篇優(yōu)質(zhì)英文文章。
  • 網(wǎng)易云電臺「極光日報**」,上下班路上為你讀報。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,533評論 19 139
  • Correctness AdapterViewChildren Summary: AdapterViews can...
    MarcusMa閱讀 9,051評論 0 6
  • 秋天在風(fēng)雨中到來 一切似乎都還在夏天徘徊 風(fēng)中的綠色尚未變化 悄悄地清澈起涼爽 果實(shí)在枝頭壓得沉甸甸 田野里稻谷豐...
    金永輝煌閱讀 478評論 24 9
  • 若你問我為何行走如風(fēng) 我的銹劍會告訴你 我已經(jīng)年老且多病 這一切 只不過是時間搞的鬼 若你問我為何牧羊青坡 我的長...
    我沒尷尬過閱讀 331評論 0 0

友情鏈接更多精彩內(nèi)容