预备知识
- 只有在使用Android Studio时才会存在applicationId,这个值一般写在build.gradle文件中.
- 用Android Studio构建apk时,AndroidManifest.xml源文件和生成的apk中的AndroidManifest.xml会稍有变化.
构建apk之前和构建apk之后applicationId和package的作用是会发生变化的,下面分别讨论之:
构建apk之前
- applicationId:顾名思义就是应用的ID号,Android设备据此区别不同的应用,这个值一般写在build.gradle文件中.
package属性有两个用途:
- 指定生成的R类的命名空间,例如pakcage=”com.test.myapp”,那么生成的R类就是com.test.myapp.R;
- 用于明确AndroidManifest.xml源文件中没有明确指定的类的全名,典型的就是以”.”开头的类,例如android:name=”.MainActivity” 的Activity将解析为com.test.myapp.MainActivity;
构建apk之后
applicationId根本不存在了,那么Android设备怎么确定应用的applicationId呢?答案是让package属性充当applicationId的角色!这是构建系统和设备上的Android系统约定好的.
因为在构建后生成的apk中的AndroidManifest.xml会将原来声明为”.MainActivity”的Activity替换为”com.test.myapp.MainActivity”,这样package的第二个作用就没有了,并且R文件已经生成了,第一个作用也没有了,所以在apk中package属性的原有作用可以说已经没有了,构建系统会将package修改为build.gradle中applicationID的值
所以手机上的android系统就会将此属性作为applicationID注意:构建系统构建apk时首先根据package属性生成R文件,并且重命名.MainActivity这种样式的类名为全类名,之后将package修改为build.gradle中applicationID的值!
根据以上信息可以明白为什么运行时获取自身的包名为applicationID定义的值,而有可能并不是源AndroidManifest.xml中package定义的值.
我猜想造成上述现象的原因是因为android早期没有想到替换包名的问题,所以当时直接用package属性作为应用的ID,但是后来发现这样的话有的人修改应用ID会很麻烦:要改许多类的包名,如果遇到反射比较多的情况就惨了,所以提出了applicationID的概念.以上一段只是个人猜想…