Android工程中共主线差异化打包方案说明
Posted 技术博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android工程中共主线差异化打包方案说明相关的知识,希望对你有一定的参考价值。
转载请标注来源:http://www.cnblogs.com/charles04/p/9017501.html
android工程中共主线差异化打包方案说明
0、目录
- 引言
- 需求分析
- 方案描述
- 参考文献
1、引言
随着项目的不断迭代,经常需要基于同一套基线代码,release部分差异的不同APK。例如,不同的应用市场,release不同的适配版本。原始的办法一般是,从最新的基线上拉去代码分支来支持不同版本的发布。但是,这样需要同时维护不同的分支代码,从而额外增加开发和维护成本,影响正常的开发进度。
2、需求分析
同一个工程,通过差异化的设计编码,构建出两套差异化的版本,实现在同一个工程下管理不同的版本的目的。
其中,差异化版本之间,存在以下异同点:
- 不同版本之间,大部分代码相同,公用一套公共组件,底层代码等;
- 不同版本之间,需要差异化实现不同的功能,包括显示(xml)不同,逻辑(java)不同,配置(Manifest)不同等;
- 不同版本之间,包名不同;
3、方案描述
在Android Studio中,通过配置不同的productFlavors实现同一个工程下的差异化版本构建。例如,通过同一套代码,实现两个不同的产品,分别为productA和productB,具体的操作如下。
3.1. Build配置
在build中分别为productA和productB配置不同的flavors,如下:
1 android {
2 compileSdkVersion 24
3 buildToolsVersion "24.0.2"
4 defaultConfig {
5 applicationId "com.example.product"
6 minSdkVersion 20
7 targetSdkVersion 24
8 versionCode 1
9 versionName "1.0.0.0"
10 }
11
12 productFlavors {
13 productA {
14 applicationId "com.example.product.a"
15 versionName "1.0.0.1"
16 }
17
18 productB {
19 applicationId "com.example.product.b"
20 versionName "1.0.0.2"
21 }
22 }
23
24 buildTypes {
25 release {
26 minifyEnabled false
27 proguardFiles getDefaultProguardFile(\'proguard-android.txt\'), \'proguard-rules.pro\'
28 }
29 }
30 }
其中,不同flavors下面设定的applicationId即为对应版本的进程名称,也即package name。
Tips:Android工程中build中设定的applicationId和Manifest中设置的package(name)有什么区别?
解释:application id与package name在Android工程中分工明确,其中:
(1).application id 负责 App 的进程 ID
(2).package name 负责 R 的包名以及 Manifest 中 Activity 等四大组件的相对包名
如果 build.gradle 中没有指定 applicationId,那么 application id 的默认值就是 manifest 的 package 属性值。
3.2. 工程结构
在src/main目录下新建两个同级目录productA与productB,目录的名称要与productFlavors中设定的工程名保持一致。如下所示:
productA/productB与main目录一样,也可以有自己的java包,res资源文件和AndroidManifest配置文件。其中,对于productA和productB来说,main目录下的文件和资源是共享的,而productA与productB下的文件和资源是对应的product特有的,在这里可以做一些差异化的编码,达到共主线,差异化逻辑的效果。
值得注意的是,productA和productB中可以存在同名文件,在gradle编译的时候,会自动链接各自product的文件。这样就给编码带来了极大的便利。例如:
- 想要做到差异化显示,只需要在对应的product目录给同一个Activity配置不同的同名xml;
- 想要实现不同的页面逻辑,只需要在对应的product目录中实现各自的同名Activitry;
- 想要获取差异化数据,只需要在对应的product目录中配置不同内容的同名的Config;
- 想要对同一个Activity实现不同的配置(启动模式,过滤模式等),只需要在对应的product中配置不同的Manifest;
- 想要在不同版本中依赖不同的Module或jar包,也可以通过差异化的依赖来实现,如下:
1 dependencies {
2 compile project(\':common-lib\')
3 productACompile project(\':common-entity\')
4 productBCompile project(\':common-overseas-entity\')
5 }
- 想要在Manifest中配置不同的渠道值,只需要在productFlavors中配置不同的manifestPlaceholders,如下:
1 productFlavors{
2 productA{
3 manifestPlaceholders = [CHANNEL:"productA"]
4 }
5 productB{
6 manifestPlaceholders = [CHANNEL:"productB"]
7 }
8 }
对应的Manifest配置如下:
1 <meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL}"/>
类似这样的操作,可以在多渠道差异化打包过程中,减少了很多不必要的逻辑判断。这样一来,不仅代码更加健壮,而且代码可读性大大提升。
3.3. 编译命令
代码编写完成之后,就可以通过gradle编译出差异化的版本。与一般的编译情况一样,差异化编译版本也有两种编译途径:
(1). 通过gradle视图,直接点击编译,如下:
分别点击assembleProductA和assembleProductB就可以差异化的编译出productA和productB的包;
(2). 通过命令行编译;
以编译ProductB为例,
1 gradlew assembleProductB:编译productB的release和debug包;
2 gradlew assembleProductBDebug:编译productB的debug包;
3 gradlew assembleProductBRelease:编译productB的release包;
3.4. 运行
编译之后,就可以生成可执行的二进制文件,如下:
分别安装app-productA-debug.apk和app-productB-debug.apk,可以发现手机上生成了两个不一样的apk,如下:
这是因为,二者的keystore虽然一致,但是不同的product的applicationId不一致,所以对应的签名信息是有区别的。所以,前后安装两个APK不会覆盖。
分别点击进行两个APK,跳转的流程如下:
可以发现,通过上述方法已经实现了共主线差异打包的能力。
4、参考文献
- http://www.jianshu.com/p/81eff804d1b8
- http://www.jianshu.com/p/ceb354f41f0e
- http://www.jianshu.com/p/4677efee7214
- http://blog.csdn.net/crazyman2010/article/details/53471162
- http://www.jianshu.com/p/1ae5c85d2ff2
以上是关于Android工程中共主线差异化打包方案说明的主要内容,如果未能解决你的问题,请参考以下文章
Unity3DUnity 中使用 C# 调用 Java ③ ( C# 调用 Java 实例 | 进行 Android 工程打包 | Android Studio 中运行 Android 工程 )
Unity3DUnity 中使用 C# 调用 Java ③ ( C# 调用 Java 实例 | 进行 Android 工程打包 | Android Studio 中运行 Android 工程 )
Android Studio 打包时 Signature Version 选择 V1 V2 说明
Android Studio3.0 flavorDimensions多维度理解(版本差异化打包) : flavorDimensions dimension