最近要做一个 android 产品的变种版本,需要编出不同版本,每个版本有不同的包名、图标等等,和一些特有的逻辑。

很久之前做过类似的工作,当时没有 gradle, 用的方法是把公共代码抽成一个 library,不同版本建一个工程引用公共 libery。但是这种方法每个版本要建一个工程,工作量较大,并且会有一些重复代码,不好维护。

现在的工程是用 gradle 构建的,网上查了一下应该用 product flavors 做这个事情,之前没接触过,现在把方法记录在这里。

定义多版本

Product flavors 用法很简单。在 build.gradle 的 android 段中加入

android
{
... productFlavors {
demo1 {
applicationId "com.mycompany.demo1"
}
demo2 {
applicationId "com.mycompany.demo2"
}
}
}

gradle 的任务里就会多了 assembleDemo1 和 assembleDemo2,可以编出不同的版本。applicationId 是 apk 的包名,而且这个 applicationId 不会影响资源类 R 所在的包,在代码里不同版本引用的 class R 都是在 AndroidManifest.xml 所指定的 package 里,所以很方便。

Android Studio 界面左下角有个Build Variants 的选项,可以选择当前编那个版本。

添加多版本的资源文件目录

在 sourceSets段中可以设置不同版本的代码和资源位置。

 sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/java']
aidl.srcDirs = ['src/main/java']
renderscript.srcDirs = ['src/main/java']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
demo1.java.srcDirs = ['src/demo1/java']
demo1.res.srcDirs = ['src/demo1/res']
demo2.java.srcDirs = ['src/demo2/java']
demo2.res.srcDirs = ['src/demo2/res']
}

这里 main 是公共的代码和资源,demo1 及 demo2 中找不到的文件会在 main 中查找,因此每个版本下只要放自己改动过的文件就可以了。

多版本配置

在 productFlavors 中,可以指定配置

productFlavors {
demo1 {
applicationId "com.mycompany.demo1"
buildConfigField 'String', 'HOST', '"http://www.baidu.com"'
}
demo2 {
applicationId "com.mycompany.demo2"
buildConfigField 'String', 'HOST', '"http://www.google.com"'
}

在代码中可以用 BuildConfig.HOST 来访问不同的配置。

控制不同权限

如果不同版本权限不同,可以用 manifestPlaceholders 修改 AndroidManifest.xml 中的内容来实现。

AndroidManifest.xml 中:

    <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="${billPermission}" />

对 billPermission 设置不同的值,可以控制有没有内购权限:

    productFlavors {
demo1 {
applicationId "com.mycompany.demo1"
manifestPlaceholders = [
"billPermission": "com.android.vending.BILLING",
]
}
demo2 {
applicationId "com.mycompany.demo2"
manifestPlaceholders = [
"billPermission": "android.permission.INTERNET",
]
}

只有 demo1 有 com.android.vending.BILLING 权限。demo2 由于 INTERNET 权限和前面重复,会被忽略掉

Product Flavor 还有许多可以控制的地方,了解更多可以访问 Android Plugin DSL Referrence

使用 gradle 编译多版本 android 应用的更多相关文章

  1. 深入理解gradle编译-Android基础篇

    深入理解gradle编译-Android基础篇 导读 Gradle基于Groovy的特定领域语言(DSL)编写的一种自动化建构工具,Groovy作为一种高级语言由Java代码实现,本文将对Gradle ...

  2. Android 项目利用 Android Studio 和 Gradle 打包多版本APK

    在项目开发过程中,经常会有需要打包不同版本的 APK 的需求. 比如 debug版,release版,dev版等等. 有时候不同的版本中使用到的不同的服务端api域名也不相同. 比如 debug_ap ...

  3. 利用 Android Studio 和 Gradle 打包多版本APK

    在项目开发过程中,经常会有需要打包不同版本的 APK 的需求. 比如 debug版,release版,dev版等等. 有时候不同的版本中使用到的不同的服务端api域名也不相同. 比如 debug_ap ...

  4. 【Android 应用开发】 Android 各种版本简介 ( Support 支持库版本 | Android Studio 版本 | Gradle 版本 | jcenter 库版本 )

    初学者遇到 Android Studio, 导入工程后, 会出现各种奇葩错误, 如果管理好各个插件, gradle, SDK, SDK Tools, 各种官方依赖库 的版本, 会将错误大大的减少; 这 ...

  5. Android Studio工程Gradle编译报错

    一.环境的搭建: 首先搭建好AndroidStudio环境.我使用的是Ubuntu 12.04系统(由于此机器还要运行其他程序,为避免兼容性问题,暂未更新到最新,而继续沿用此稳定版),java和jdk ...

  6. Android提升Gradle编译速度或减少Gradle编译时间.md

    目录 Android如何提升Gradle编译速度或减少Gradle编译时间 最终优化方案 优化效果比对 将所有项目源码,各种缓存临时目录都移动到高性能SSD磁盘上 gradle.properties ...

  7. 升级gradle后。需要修改jenkin 编译java版本从1.8 到11

    错误提示 * What went wrong: A problem occurred evaluating project ':App'. > Failed to apply plugin 'c ...

  8. Android Studio Gradle编译项目报错

    Gradle project sync failed Android Studio每次更新版本都会更新Gradle这个插件,但由于长城的问题每次更新都是失败,又是停止在Refreshing Gradl ...

  9. 第三篇:gradle 编译 Android app 概览

    引言:经过上两篇的论述,我们已经从代码到架构都简单的熟悉了一遍,理论上,只要知道android app的编译过程,我们大可以自己写一份用gradle编译app的插件,插件内将将整个流程用Task的依赖 ...

随机推荐

  1. JavaWeb项目开发案例精粹-第3章在线考试系统-002配置文件及辅助类

    1. <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5&qu ...

  2. 2014--9=17 软工二班 MyEclipse blue==1

    package cn.rwkj.test; import java.io.IOException; import java.net.ServerSocket; import java.net.Sock ...

  3. JSON操作技巧

    JSONObject.JSONArray 最近两个星期接触最多的就是json和map了. 之前用到的json,就是一个键对应一个值,超级简单的一对一关系.现在用到的json那可以层层嵌套啊,刚开始接触 ...

  4. Spring面向切面编程(AOP,Aspect Oriented Programming)

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术. ...

  5. java工具类–自动将数据库表生成javabean

    最近和数据库的表打交道挺多的,因为暂时做的是接口活. 在这过程中发现要把表转换成对应的javabean类型,字段少的表还行,如果不小心碰到几十个字段的他妈的写起来就有点麻烦了,万一碰到几百个的呢,那不 ...

  6. 写给系统管理员的25个PHP安全实践

    PHP是广泛使用的开源服务端脚本语言.通过HTTP或HTTPS协议,Apache Web服务允许用户访问文件或内容.服务端脚本语言的错误配置会导致各种问题.因此,PHP应该小心使用.以下是为系统管理员 ...

  7. WC约束示使用

    1.接口中添加时要注意Xml序列化标签不要随意添加啊.[webInvoke].[OpertorContract]这2个约束就行了.不然,直接坑死啊.

  8. Eclipse中Python插件PyDev的安装与配置流程

    安装PyDev插件的两种安装方法: 方法1.下载地址:http://sourceforge.net/projects/pydev/files/,将下载的PyDev解压(目前最新版本 PyDev 4.5 ...

  9. 利用序列化的方式实现C#深复制和浅复制

    代码如下:具体看注释 [Serializable] public class A { public virtual string Name { get; set; } public int Age { ...

  10. UVa 1636 (概率) Headshot

    既然是第一道概率题,就正儿八经地分析一下吧. 题意: 有一个左轮枪,里面随机装了或者没装子弹,用一个01序列表示.现在已知扣动第一次扳机没有子弹,问是继续扣动扳机还是随机转动一下再扣,那种选择使得第二 ...