http://tech.meituan.com/mt-apk-adaptation.html

概述

前一篇文章(美团Android自动化之旅—生成渠道包)介绍了Android中几种生成渠道包的方式,基本解决了打包慢的问题。

但是,随着渠道越来越多,不同渠道对应用的要求也不尽相同。例如,有的渠道要求美团客户端的应用名为美团,有的渠道要求应用名为美团团购。又比如,有些渠道要求应用不能使用第三方统计工具(如flurry)。总之,每次打包都需要对这些渠道进行适配。

之前的做法是为每个需要适配的渠道创建一个Git分支,发版时再切换到相应的分支,并合并主分支的代码。适配的渠道比较少的话这种方式还可以接受,如果分支比较多,对开发人员来说简直就是噩梦。还好,自从有了Gradle flavor,一切都变得简单了。本文假定读者使用过Gradle,如果还不了解建议先阅读相关文档。

Flavor

先来看build.gradle文件中的一段代码:

android {
.... productFlavors {
flavor1 {
minSdkVersion 14
}
}
}

上例定义了一个flavor:flavor1,并指定了应用的minSdkVersion为14(当然还可以配置更多的属性,具体可参考相关文档)。与此同时,Gradle还会为该flavor关联对应的sourceSet,默认位置为src/<flavorName>目录,对应到本例就是src/flavor1

接下来,要做的就是根据具体的需求在build.gradle文件中配置flavor,并添加必要的代码和资源文件。以flavor1为例,运行gradle
assembleFlavor1
命令既可生成所需的适配包。下面主要介绍美团团购Android客户端的一些适配案例。

案例

使用不同的包名

美团团购Android客户端之前有两个版本:手机版(com.meituan.group)和hd版(com.meituan.group.hd),两个版本使用了不同的代码。目前hd版对应的代码已不再维护,希望能直接使用手机版的代码。解决该问题可以有多种方法,不过使用flavor相对比较简单,示例如下:

productFlavors {
hd {
applicationId "com.meituan.group.hd"
}
}

上面的代码添加了一个名为hd的flavor,并指定了应用的包名为com.meituan.group.hd,运行gradle
assembleHd
命令即可生成hd适配包。

控制是否自动更新

美团团购Android客户端在启动时会默认检查客户端是否有更新,如果有更新就会提示用户下载。但是有些渠道和应用市场不允许这种默认行为,所以在适配这些渠道时需要禁止自动更新功能。

解决的思路是提供一个配置字段,应用启动的时候检查该字段的值以决定是否开启自动更新功能。使用flavor可以完美的解决这类问题。

Gradle会在generateSources阶段为flavor生成一个BuildConfig.java文件。BuildConfig类默认提供了一些常量字段,比如应用的版本名(VERSION_NAME),应用的包名(PACKAGE_NAME)等。更强大的是,开发者还可以添加自定义的一些字段。下面的示例假设wandoujia市场默认禁止自动更新功能:

android {
defaultConfig {
buildConfigField "boolean", "AUTO_UPDATES", "true"
} productFlavors {
wandoujia {
buildConfigField "boolean", "AUTO_UPDATES", "false"
}
} }

上面的代码会在BuildConfig类中生成AUTO_UPDATES布尔常量,默认值为true,在使用wandoujia flavor时,该值会被设置成false。接下来就可以在代码中使用AUTO_UPDATES常量来判断是否开启自动更新功能了。最后,运行gradle
assembleWandoujia
命令即可生成默认不开启自动升级功能的渠道包,是不是很简单。

使用不同的应用名

最常见的一类适配是修改应用的资源。例如,美团团购Android客户端的应用名是美团,但有的渠道需要把应用名修改为美团团购;还有,客户端经常会和一些应用分发市场合作,需要在应用的启动界面中加上第三方市场的Logo,类似这类适配形式还有很多。

Gradle在构建应用时,会优先使用flavor所属dataSet中的同名资源。所以,解决思路就是在flavor的dataSet中添加同名的字符串资源,以覆盖默认的资源。下面以适配wandoujia渠道的应用名为美团团购为例进行介绍。

首先,在build.gradle配置文件中添加如下flavor:

android {
productFlavors {
wandoujia {
}
}
}

上面的配置会默认src/wandoujia目录为wandoujia flavor的dataSet

接下来,在src目录内创建wandoujia目录,并添加如下应用名字符串资源(src/wandoujia/res/values/appname.xml):

<resources>
<string name="app_name">美团团购</string>
</resources>

默认的应用名字符串资源如下(src/main/res/values/strings.xml):

<resources>
<string name="app_name">美团</string>
</resources>

最后,运行gradle assembleWandoujia命令即可生成应用名为美团团购的应用了。

使用第三方SDK

某些渠道会要求客户端嵌入第三方SDK来满足特定的适配需求。比如360应用市场要求美团团购Android客户端的精品应用模块使用他们提供的SDK。问题的难点在于如何只为特定的渠道添加SDK,其他渠道不引入该SDK。使用flavor可以很好的解决这个问题,下面以为qihu360 flavor引入com.qihoo360.union.sdk:union:1.0 SDK为例进行说明:

android {
productFlavors {
qihu360 {
}
}
}
...
dependencies {
provided 'com.qihoo360.union.sdk:union:1.0'
qihu360Compile 'com.qihoo360.union.sdk:union:1.0'
}

上例添加了名为qihu360的flavor,并且指定编译和运行时都依赖com.qihoo360.union.sdk:union:1.0。而其他渠道只是在构建的时候依赖该SDK,打包的时候并不会添加它。

接下来,需要在代码中使用反射技术判断应用程序是否添加了该SDK,从而决定是否要显示360 SDK提供的精品应用。部分代码如下:

class MyActivity extends Activity {
private boolean useQihuSdk; @override
public void onCreate(Bundle savedInstanceState) {
try {
Class.forName("com.qihoo360.union.sdk.UnionManager");
useQihuSdk = true;
} catch (ClassNotFoundException ignored) { }
}
}

最后,运行gradle assembleQihu360命令即可生成包含360精品应用模块的渠道包了。

总结

适配是一项dirty工作,尤其是适配的渠道比较多的时候。上面介绍了几种使用Gradle flavor进行适配的例子,基本解决了繁杂的适配工作。

美团Android自动化之旅—适配渠道包的更多相关文章

  1. Android自动化之旅—生成渠道包

    美团Android自动化之旅—生成渠道包:http://tech.meituan.com/mt-apk-packaging.html   Android Studio系列教程六--Gradle多渠道打 ...

  2. Android-Ant自动编译打包android项目 -- 2 ----签名与渠道包

    上篇介绍了怎么使用ant自动编译打包现有的android项目,这篇将继续介绍如果如何在ant打包应用的时候加入签名信息以及自动打包渠道包. 1. 加入签名信息: 在项目的根目录下建一个ant.prop ...

  3. [转]安卓新一代多渠道打包工具Walle 解决渠道包V2签名问题

    转自https://www.jianshu.com/p/572b59829a08 为什么要打多个渠道的包? 大家都知道,android应用商店大大小小有几百个,作为一个有志向的app,就需要做到统计各 ...

  4. 使用Gradle构建Android应用的渠道包

    所有做Android App的同志们应该都知道渠道包是什么,得力于Android生态的多样性,我等写Android应用的人类每次发布App都需要面对数十个市场,而为了能够采集到市场的表现数据,就必须为 ...

  5. Android应用公布的准备——生成渠道包

    我们须要使用一个变量标明该app的渠道.通常我们能够在manifest中的application节点下声明.例如以下. <meta-data android:name="CHANNEL ...

  6. 新一代开源Android渠道包生成工具Walle

    本文转自:http://tech.meituan.com/android-apk-v2-signature-scheme.html 新一代开源Android渠道包生成工具Walle 新的应用签名方案A ...

  7. 简单快速的Android打渠道包的方法

         APK其实就是ZIP的格式,所以,解压apk后,会看到里面有个META-INF目录.   思路:由于META-INF目录并不会影响到APK的签名和运行,所以我们可以在META-INF目录里添 ...

  8. 我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!

    本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超 ...

  9. 从零开始做一个Android自动化

    移动端自动化简单说就是,写好操作app的程序,运行起来,自动执行程序和测试用例,输出执行结果,结果正确,测试通过. 自动化可以方便地完成安装/卸载.启动/运行.UI适配等环节,节省时间: 同一测试脚本 ...

随机推荐

  1. 【转载】C#中可使用string.Empty代表空字符

    在C#中,如果赋值一个字符串为空白字符串,我们一般会用“”的形式对字符串进行赋值操作,其实在C#的字符串类String类中,有个专门的常量string.Empty来代表空字符串,可直接在赋值的时候使用 ...

  2. 设置 SQL*Plus 的运行环境

    SQL*Plus 的运行环境是用来输入.执行 SQL*Plus 命令和显示返回结果的场所,设置合适的 SQL*Plus 运行环境,可以使 SQL*Plus 按照用户的要求运行和执行各种操作.set 命 ...

  3. Python学习日记(十八) 序列化模块

    什么是序列? 就是每一个元素被有序的排成一列 什么是序列化? 就是将原本的列表.字典等内容转化成字符串的过程 什么时候会用到序列化? 数据存储(把数据放在文件.数据库),网络传输等 序列化的目的 1. ...

  4. javascript_16-对象字面量

    JSON与对象字面量相似,仅仅是属性需要使用双引号引号引起. json是描述数据的一种规范 什么是JSON JavaScript Object Notation (JavaScript 对象表示形式) ...

  5. 安装folly库以及folly的ConcurrentHashMap的简单使用

    我在写grpc的实例时, 需要使用一个多线程的hash map, C++标准库中没有多线程的hash map, facebook开源的folly中存在大量的基础类, 中间存在一个高性能的hash ma ...

  6. CentOS7.x-lnmp环境下安装Discuz论坛

    1.安装lnmp.这里采用一键安装的包 yum -y install wget wget http://soft.vpser.net/lnmp/lnmp1.6-full.tar.gz 2.加压安装ln ...

  7. SVN提交错误及使用技巧

    错误1: Some of selected resources were not added to version control. Some of selected resources were n ...

  8. Linux查找工具locate和find

    linux 中有很多查找工具,今天主要讲解locate,find两个工具. 一.locate 1.性能介绍 非实时查找(数据库查找):locate 查询系统上预建的文件索引数据库 /var/lib/m ...

  9. tengine编译安装及nginx高并发内核参数优化

    Tengine Tengine介绍 Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性. Tengine的性能和稳定性已经在大型的 ...

  10. Centos 7.6 双网卡绑定实现高可用

    Centos 7.6 双网卡绑定实现高可用 作者:尹正杰 版权声明:原创作品, 谢绝转载!否则将追究法律责任. 一.Bond模式概述 当linux系统上有多个单独网卡,又想充分利用这些网卡,同时对外提 ...