Android Package Name vs. Application ID

(转载)https://zhuanlan.zhihu.com/p/25621771

简评:最熟悉的地方也会有大学问。

对于 Android 开发者来说,Package Name 应当再熟悉不过了,或许有些同学还注意到了 App 的 build.gradle 中有一个 applicationId,它的值通常都和包名一致,但其实二者是存在区别的。

<?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 的值:

可以发现应用最终的包名其实是由 applicationId 决定的,而之前 Manifest 中的 package 值主要是做两件事:

  • 指明类的路径。比如我们在 manifest 文件中声明 <activity android:name=".MainActivity">,实际会被解析为 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 拷贝进 APK 的 manifest 文件的。

如果你像上面那样在 buildTypes 中修改了 applicationId 值,那么在代码中想要获取到应用包名就需要注意,看看下面的代码:

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));
    }
}
结果分别为:
Package Name: package com.stylingandroid.packagename
Application ID: com.stylingandroid.packagename.debug

那为什么 Android 要在编译的最后才将 application ID 拷贝进 manifest 文件中呢?

理由很简单,如果 BuildConfig.java 和 R.java 文件使用了 applicationId 而不是 package name,编译的时候路径会出错。

原文: Package Name vs. Application ID

扩展阅读:

欢迎关注:知乎专栏「极光日报」,每天为 Makers 导读三篇优质英文文章。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值