Android应用开发中的进程名,包名,applicationId
2016-06-30 22:17
363 查看
包名是安卓应用apk的唯一标识,安卓系统管理应用时,也是以包名索引。包名在AndroidManifest.xml中定义。在一个安卓应用程序工程创建之初,包名就已经确定。包名更多的是一个编译时概念。由android IDE自动生成的类,比如R、BuildConfig,都是以AndroidManifest.xml中定义的包名来构造类名,譬如,包名为“com.android.helloworld”,对应生成“com.android.helloworld.R”“com.android.helloworld.BuildConfig”。在需要使用的类中,需要imort,import语句也将保留在源代码中。
android应用在被启动时,对应的进程的进程名一般就是包名。android应用一般是运行在自己的进程中,除非通过AndroidManifest.xml中application定义中通过android:process字段指定运行在其他进程中(这种机制有特殊限定条件)。
applicationId是Android Studio提供的一种新的机制,可以在app/build.gradle中定义,譬如:
Android Studio默认生成的app/build.gradle中,applicationId与AndroidManifest.xml中定义的包名一致。但显然,这两个值是可以独立设置的,可以不同。注意,在修改applicationId后,前面提到的IDE自动生成的类(譬如R、BuildConfig),包名不会被更新,仍然是AndroidManifest.xml中定义的包名,使用他们的类中的import语句也不需要更改。
但在修改applicationId之后,查看运行时进程名,会变成新的applicationId。在程序内运行时调用Context.getPackageName(),得到的仍然是新的applicationId。怀疑实现方式是build过程中,擦除并更新了AndroidManifest.xml中的package字段。使用apktool对编译生成的apk反编译,查看AndroidManifest.xml,发现确实是修改成了applicationId的值,验证了上述假设。
如上分析,对于applicationId的理解已经清晰。对于一个大的工程,修改包名的成本过高,几乎不可取。而经常会出现一个工程需要出不同版本,譬如收费版和免费版。这样就可以通过简单修改app/build.gradle中的applicationId来改变最终apk的包名,这样对于安卓手机来说,就是不同的app;同时,又不影响到开发编译时的代码一致性。
最后,说一个这种机制的坑。对于上文提到的自动生成的Java类(譬如R、BuildConfig),如果不是通过正常的import,而是通过在运行时调用Context.getPackageName()得到包名拼接成类名再用反射获取类,这样就会遇到ClassNotFoundException。需注意尽量不要用这种方式。反射虽然能让人体会到超越Java数据封装规则之上的快感,但是也有各种暗礁等着。
android应用在被启动时,对应的进程的进程名一般就是包名。android应用一般是运行在自己的进程中,除非通过AndroidManifest.xml中application定义中通过android:process字段指定运行在其他进程中(这种机制有特殊限定条件)。
applicationId是Android Studio提供的一种新的机制,可以在app/build.gradle中定义,譬如:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.3" defaultConfig { applicationId "com.android.helloworld" minSdkVersion 21 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' }
Android Studio默认生成的app/build.gradle中,applicationId与AndroidManifest.xml中定义的包名一致。但显然,这两个值是可以独立设置的,可以不同。注意,在修改applicationId后,前面提到的IDE自动生成的类(譬如R、BuildConfig),包名不会被更新,仍然是AndroidManifest.xml中定义的包名,使用他们的类中的import语句也不需要更改。
但在修改applicationId之后,查看运行时进程名,会变成新的applicationId。在程序内运行时调用Context.getPackageName(),得到的仍然是新的applicationId。怀疑实现方式是build过程中,擦除并更新了AndroidManifest.xml中的package字段。使用apktool对编译生成的apk反编译,查看AndroidManifest.xml,发现确实是修改成了applicationId的值,验证了上述假设。
如上分析,对于applicationId的理解已经清晰。对于一个大的工程,修改包名的成本过高,几乎不可取。而经常会出现一个工程需要出不同版本,譬如收费版和免费版。这样就可以通过简单修改app/build.gradle中的applicationId来改变最终apk的包名,这样对于安卓手机来说,就是不同的app;同时,又不影响到开发编译时的代码一致性。
最后,说一个这种机制的坑。对于上文提到的自动生成的Java类(譬如R、BuildConfig),如果不是通过正常的import,而是通过在运行时调用Context.getPackageName()得到包名拼接成类名再用反射获取类,这样就会遇到ClassNotFoundException。需注意尽量不要用这种方式。反射虽然能让人体会到超越Java数据封装规则之上的快感,但是也有各种暗礁等着。
相关文章推荐
- class_getInstanceMethod和class_getClassMethod的区别
- Unity3d之按键
- Unity3d之截图
- Android自定义饼状图,支持点击弹出扇形
- iOS多线程基础
- Android对敏感数据进行MD5加密(基础回顾)
- IOS 学习之路(一) 徒手写界面(1)
- iOS开发多线程篇 10 —NSOperation基本操作
- 精通IOS开发-布局基础
- 用FragmentTabHost达到现在市面上的主流导航页面
- Swift 函数总结
- App开机自启动
- win8.1 thinkpad 安装virtualbox,ubuntu的准备工作(大白型)
- android基础—新建一个Activity
- Android studio 项目Gradle升级后报错Session 'app': Error Launching activity
- android 二维码 扫描与生成(内置)
- Half精度解析
- Android 使用Mina的Nio实现客户端服务器通信
- 最新的Android版本和API Level的对应关系表
- Quartz 2D简介