码迷,mamicode.com
首页 > 移动开发 > 详细

Android工程中共主线差异化打包方案说明

时间:2018-05-10 01:06:15      阅读:509      评论:0      收藏:0      [点我收藏+]

标签:col   过程   技术   命令   链接   提升   没有   ref   jar   

Android工程中共主线差异化打包方案说明

 

  1. 简介

智能家居APP出海版本已启动开发,由于出海版本维护周期较长,在国内Master分支的基础上,为海外版本拉取单独的分支,会额外增加开发和维护成本,影响正常的开发进度。

  1. 需求分析

同一个工程,通过差异化的设计编码,构建出两套差异化的版本,实现在同一个工程下管理不同的版本的目的。

其中,差异化版本之间,存在以下异同点:

  1. 不同版本之间,大部分代码相同,公用一套公共组件,底层代码等;
  2. 不同版本之间,需要差异化实现不同的功能,包括显示(xml)不同,逻辑(java)不同,配置(Manifest)不同等;
  3. 不同版本之间,包名不同;
  1. 方案描述

Android Studio中,通过配置不同的productFlavors实现同一个工程下的差异化版本构建。例如,通过同一套代码,实现两个不同的产品,分别为productAproductB,具体的操作如下。

  1. build配置

在build中分别为productA和productB配置不同的flavors,如下:

android {

    compileSdkVersion 24

    buildToolsVersion "24.0.2"

    defaultConfig {

        applicationId "com.example.product"

        minSdkVersion 20

        targetSdkVersion 24

        versionCode 1

        versionName "1.0.0.0"

    }

 


					productFlavors {

        productA {

            applicationId "com.example.product.a"

            versionName "1.0.0.1"

        }

 

        productB {

            applicationId "com.example.product.b"

            versionName "1.0.0.2"

        }

    }

 

    buildTypes {

        release {

            minifyEnabled false

            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘

        }

    }

}

其中,不同flavors下面设定的applicationId即为对应版本的进程名称,也即package name

TipsAndroid工程中build中设定的applicationIdManifest中设置的package(name)有什么区别?
					

解释:application idpackage nameAndroid工程中分工明确,其中:
					

?    application id 负责 App 的进程 ID

?    package name 负责 R 的包名以及 Manifest  Activity 等四大组件的相对包名
					

如果 build.gradle 中没有指定 applicationId,那么 application id 的默认值就是 manifest package 属性值。

  1. 工程结构

src/main目录下新建两个同级目录productAproductB,目录的名称要与productFlavors中设定的工程名保持一致。如下所示:

 

技术分享图片

productA/productBmain目录一样,也可以有自己的java包,res资源文件和AndroidManifest配置文件。其中,对于productAproductB来说,main目录下的文件和资源是共享的,而productAproductB下的文件和资源是对应的product特有的,在这里可以做一些差异化的编码,达到共主线,差异化逻辑的效果。

值得注意的是,productAproductB中可以存在同名文件,在gradle编译的时候,会自动链接各自product的文件。这样就给编码带来了极大的便利。例如:

  • 想要做到差异化显示,只需要在对应的product目录给同一个Activity配置不同的同名xml
  • 想要实现不同的页面逻辑,只需要在对应的product目录中实现各自的同名Activitry
  • 想要获取差异化数据,只需要在对应的product目录中配置不同内容的同名的Config
  • 想要对同一个Activity实现不同的配置(启动模式,过滤模式等),只需要在对应的product中配置不同的Manifest
  • 想要在不同版本中依赖不同的Modulejar包,也可以通过差异化的依赖来实现,如下:

dependencies {

    compile project(‘:common-lib‘)

    productACompile project(‘:common-entity‘)

    productBCompile project(‘:common-overseas-entity‘)

} 

 

  • 想要在Manifest中配置不同的渠道值,只需要在productFlavors中配置不同的manifestPlaceholders,如下:

productFlavors{

        productA{

            manifestPlaceholders = [CHANNEL:"productA"]

        }

        productB{

            manifestPlaceholders = [CHANNEL:"productB"]

        }

} 

对应的Manifest配置如下:

<meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL}"/>

类似这样的操作,可以在多渠道差异化打包过程中,减少了很多不必要的逻辑判断。这样一来,不仅代码更加健壮,而且代码可读性大大提升。

  1. 编译命令

代码编写完成之后,就可以通过gradle编译出差异化的版本。与一般的编译情况一样,差异化编译版本也有两种编译途径:

  1. 通过gradle视图,直接点击编译;

    如下:

技术分享图片

 

分别点击assembleProductAassembleProductB就可以差异化的编译出productAproductB的包;

  1. 通过命令行编译;

以编译ProductB为例,

  • gradlew assembleProductB:编译productBreleasedebug包;
  • gradlew assembleProductBDebug:编译productBdebug包;
  • gradlew assembleProductBRelease:编译productBrelease包;

 

  1. 运行

编译之后,就可以生成可执行的二进制文件,如下:

技术分享图片

 

分别安装app-productA-debug.apkapp-productB-debug.apk,可以发现手机上生成了两个不一样的apk,如下:

技术分享图片

这是因为,二者的keystore虽然一致,但是不同的productapplicationId不一致,所以对应的签名信息是有区别的。所以,前后安装两个APK不会覆盖。

 

分别点击进行两个APK,跳转的流程如下:

技术分享图片

可以发现,通过上述方法已经实现了共主线差异打包的能力。

 

  1. 参考文献

  1. http://www.jianshu.com/p/81eff804d1b8
  2. http://www.jianshu.com/p/ceb354f41f0e
  3. http://www.jianshu.com/p/4677efee7214
  4. http://blog.csdn.net/crazyman2010/article/details/53471162
  5. http://www.jianshu.com/p/1ae5c85d2ff2

 

Android工程中共主线差异化打包方案说明

标签:col   过程   技术   命令   链接   提升   没有   ref   jar   

原文地址:https://www.cnblogs.com/charles04/p/9017501.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!