最近在项目中遇到需要实现 Apk 多渠道、定制化打包, Google 、百度查找了一些资料,成功实现了上述功能,在此记录以备不时之需,温故而知新,可以为师矣~
需求可以总结如下:
如何实现多个 Apk 安装在同一设备
在之前的印象中,同一个应用在同一设备上只能安装一个,除非手动修改 AndroidManifest.xml 文件中的包名( package ),但这么做的后果就是新的应用真的是新的应用,旧版应用再也收不到更新。而现在你通过 Gradle,你可以轻松构建多个不同版本的应用,并且在同一设备上安装使用。
这里要用到 productFlavors ,productFlavors 可以用来自定义应用构建版本,我们可以用其 applicationId 属性来实现多个 Apk 安装在同一设备上。
build.gradle 中部分配置代码如下:
- android {
- compileSdkVersion 24
- buildToolsVersion "24.0.1"
- //默认配置,所有 productFlavors 都会继承 defaultConfig 中配置的属性
- defaultConfig {
- //默认的 applicationId,一般与 AndroidManifest.xml 文件 package属性相同
- applicationId "com.littlejie.multichannel"
- minSdkVersion 15
- targetSdkVersion 24
- versionCode 1
- versionName "1.0"
- }
- // productFlavors 定义了一个应用的自定义构建版本
- //一个单一的项目可以同时定义多个不同的 flavor 来改变应用的输出。
- // productFlavors 这个概念是为了解决不同的版本之间的差异非常小的情况,通常用于区分同一个应用的不同渠道/客户等,可包含少量业务功能差别。
- // productFlavors 中的 flavor 不能跟 buildType 中的一样,否则会报: "ProductFlavor names cannot collide with BuildType names"
- productFlavors {
- //默认版本,不设置 applicationId ,继承 defaultConfig 中的配置
- flavors_default {
- }
- //开发版本, applicationId 替换为 com.littlejie.multichannel.dev
- flavors_dev {
- applicationId "com.littlejie.multichannel.dev"
- }
- //发布版本, applicationId 替换为 com.littlejie.multichannel.release
- flavors_release {
- applicationId "com.littlejie.multichannel.release"
- }
- }
- }
MainActivity.java:
- public class MainActivity extends Activity {
- private static final String TAG = MainActivity.class.getSimpleName();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Log.d(TAG, "package name = " + this.getPackageName());
- }
- }
在 Android Studio 中执行如下命令:
- //打 debug 包,gradle 命令会在后面 `gradle task`中详细讲述
- gradle clean assembleDebug
打包完成后,将 Apk 安装到模拟器(adb install name.apk),运行,log 如下:
flavors_default:
- 09-17 22:43:55.390 19747-19747/com.littlejie.multichannel D/MainActivity: package name = com.littlejie.multichannel
flavors_dev:
- 09-17 22:11:30.860 2638-2638/com.littlejie.multichannel.dev D/MainActivity: package name = com.littlejie.multichannel.dev
flavors_release:
- 09-17 22:44:55.610 20650-20650/com.littlejie.multichannel.release D/MainActivity: package name = com.littlejie.multichannel.release
从这里可以看出,不同 flavor 的 package name 被 applicationId 替换掉了,而且同一个模拟器上可以同时安装以上三个应用。
下面我们再看看 AndroidManifest.xml 中发生了什么变化。这里需要用到 aapt 来查看 AndroidManifest.xml 的信息: