Android Package Name vs. Application ID

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

对于 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 导读三篇优质英文文章。
  • 网易云电台「极光日报**」,上下班路上为你读报。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 178,127评论 25 709
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,423评论 19 139
  • Correctness AdapterViewChildren Summary: AdapterViews can...
    MarcusMa阅读 9,021评论 0 6
  • 秋天在风雨中到来 一切似乎都还在夏天徘徊 风中的绿色尚未变化 悄悄地清澈起凉爽 果实在枝头压得沉甸甸 田野里稻谷丰...
    金永辉煌阅读 476评论 24 9
  • 若你问我为何行走如风 我的锈剑会告诉你 我已经年老且多病 这一切 只不过是时间搞的鬼 若你问我为何牧羊青坡 我的长...
    我没尴尬过阅读 326评论 0 0

友情链接更多精彩内容