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

  1. 简介

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

  1. 需求分析

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

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

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

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

  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。

Tips:Android工程中build中设定的applicationId和Manifest中设置的package(name)有什么区别?
					
解释:application id与package name在Android工程中分工明确,其中:
					
?    application id 负责 App 的进程 ID
?    package name 负责 R 的包名以及 Manifest 中 Activity 等四大组件的相对包名
					

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

  1. 工程结构

在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;
  • 想要在不同版本中依赖不同的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视图,直接点击编译;

    如下:

分别点击assembleProductA和assembleProductB就可以差异化的编译出productA和productB的包;

  1. 通过命令行编译;

以编译ProductB为例,

  • gradlew assembleProductB:编译productB的release和debug包;
  • gradlew assembleProductBDebug:编译productB的debug包;
  • gradlew assembleProductBRelease:编译productB的release包;
  1. 运行

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

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

这是因为,二者的keystore虽然一致,但是不同的product的applicationId不一致,所以对应的签名信息是有区别的。所以,前后安装两个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

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

时间: 2024-10-12 20:40:08

Android工程中共主线差异化打包方案说明的相关文章

Gradle实战:Android多渠道打包方案汇总

查看原文:http://blog.csdn.net/u010818425/article/details/52319382 Gradle实战系列文章: <Gradle基本知识点与常用配置> <Gradle实战:不同编译类型的包同设备共存> <Gradle实战:发布aar包到maven仓库> <Gradle实战:执行sql操作hive数据库> 本文将延续之前几篇博客的风格,先从基本概念入手,这有助于我们对后文的理解: 在后续的代码中如果忘了某个概念的具体意义,

Ant编译打包Android工程流程

一.Ant编译打包android工程步骤 二.Ant apk签名 1.keystore签名    定义自己的签名文件 生成keystore文件:keytool -genkey -alias android.keystore -keyalg RSA - validity 20000 -keystore android.keystore 对应的java命令:jarsigner -verbose -keystore android.keystore -signedjar android_signed.

Android 多渠道打包方案

常规Build 我们先来回顾一下通过Ant或者Gradle进行多渠道批量打包,通常是在AndroidManifest中配置: <meta-data android:name="CHANNEL" android:value="xxx" /> meta-data通过配置value来动态改变渠道名称,然后我们可以在代码中这样去获取Channel private String getChannelNameFromManifest(){ try { return

Gradle 差异化构建

Compile 默认的依赖方式,任何情况下都会依赖. Provided 只提供编译时依赖,打包时不会添加进去. Apk 只在打包Apk包时依赖,这个应该是比较少用到的. TestCompile 只在测试时依赖 DebugCompile 只在Debug构建时依赖 ReleaseCompile 只在Release构建时依赖 1.实现差异化构建 这里我们在src目录下建立debug目录和release目录,并在这两个目录下面建立一个SdkManager类,这里要注意debug和release的包结构需

Android反编译和二次打包实战

作为Android开发者,工作中少不了要反编译别人的apk,当然主要目的还是为了学习到更多,取彼之长,补己之短.今天就来总结一下Android反编译和二次打包的一些知识.首先声明本文的目的是为了通过例子讲解反编译和二次打包的原理和方法,继而作为后续讲解防止二次打包和App安全的依据,并不是鼓励大家去重新打包别人的App,盗取他人劳动成果. 本文首先介绍几种Android反编译工具的使用,然后实现在不需要知道源代码的情况下,仅通过修改反编译得到的smali文件实现修改apk逻辑功能的目的. And

全陷阱破解:在Linux环境下的Jenkins中持续集成Android工程

本方案以 RHEL / Centos 64位Linux操作系统为例,因为这是目前最常见的服务器环境. 一.安装Java SDK. 建议,不要使用诸如yum之类的玩意自动安装,因为openJDK之类的东东最终各种幺蛾子跑不起来.老老实的去oracle网站下载至少Java7 64位的最终版本,手动安装之,配置好系统path和JAVA_HOME环境变量. vim ~/.bash_profile export JAVA_HOME=<Java安装路径> PATH=$PATH:$JAVA_HOME/bin

Android逆向分析(2) APK的打包与安装

http://blog.zhaiyifan.cn/2016/02/13/android-reverse-2/ 2/18日增加对aidl和java编译的描述. 前言 上一次我们反编译了手Q,并遇到了Apktool反编译直接crash的问题,虽然笔者很想在这次解决这个问题,但在解决途中,发现该保护依赖于很多知识,所以本次先插入一下,正所谓知其然知其所以然,授之鱼不如授之以渔,只有知道一些基本原理,才能让我们以后能自行解决更多问题. 那么,你知道么?从我们在Android Studio中,点击run,

利用maven实现差异化配置

回顾过去 生产环境,测试环境,开发环境在不同的环境下会有各种各样的配置,比如数据库链接地址,账户名,密码等等.不同环境下都需要配置,但是配置却又不同.以前分享过一篇文章,介绍了我之前A公司的差异化配置实现( http://www.cnblogs.com/abcwt112/p/5203348.html  原理就是增加一个classpath目录,把差异化配置都放在这个目录下,然后差异化文件不打包.这样差异化配置就会直接读取自指定的classpath下的文件)..这次我想来分享一下怎么使用maven来

Unity编译Android的原理解析和apk打包分析

作者介绍:张坤 最近由于想在Scene的脚本组件中,调用Android的Activity的相关接口,就需要弄明白Scene和Activity的实际对应关系,并对Unity调用Android的部分原理进行了研究. 本文主要探讨Scene和Activity之间的关系,以及Unity打包apk和Android studio打包apk的差别在什么地方?找到这种差别之后,可以怎么运用起来? 本文需要用到的工具: Android反编译工具--apktool Android studio自带的反编译功能 一.