我不是诗人,写不出厦门的美;我不是歌手,唱不出厦门的情;我不是画家,画不出厦门的景。
我只是一名程序员,我只能用我的眼,我的心去看去感受,那久违的海风吹拂着脸颊,好似内心那一份烦躁与沉重也随着海风飘向了远方 . . . . . .
一、Gradle多渠道打包之缘由
时间要追溯到两年前,当时我还在使用 eclipse
开发工具。兄弟事业部有款产品需要封包(使用webview打包成app),并提出了相关的需求:
针对不同商家地址(webview加载url),App名称,应用图标,欢迎页背景,状态栏颜色(背景同色)都不同,以及版本号不同。
针对不同的商家都必须打包成独立的App,不会出现覆盖安装。
针对以上的需求每次打包都需要替换App名称,应用图标,背景等资源,还必须修改包名(带来的一系列报错)。后期又提出了升级功能,又得把资源、包名修改回去,一番折腾真的欲仙欲死。后来我干脆每次都新建项目打包,业务逻辑没有变化只是资源发生了改变,代码是拷贝了一份又一份,而且商家一多,维护起来真的是找得死去活来的,加之客户提出新功能,我每个商家都需要撸一遍 . . . 神啊,谁来拯救我啊
二、自我拯救之路
在后来接触到AndroidStudio
(简称AS),逐渐的转到了AS
开发,确实比 eclipse
高效快速方便。 gradle
构建功能真心非常强大,默认有 debug ,release 版本,我们可以针对不同版本做不同配置,这不正好解决我所遇到的问题。gradle
提供了productFlavors
节点针对不同的版本做不同的配置。
比如有【四季易购】【仁仁家】【库乐购】商家需要打包。
我在每个分支下面都重新配置applicationId
这个属性,从而使打包出来的apk的包名不一样,避免了覆盖安装。
当然针对不同的商家 App名称,图标不一样。这个时候我们就需要配置manifestPlaceholders
属性,manifestPlaceholders
是一个类似HashMap
的容器,因此在manifestPlaceholders
可以配置多个属性。如下我们可以这样配置:
gradle配置:
AndroidManifest配置:
注意:节点 meta-data 的配置。
${icon}
,${app_name}
引用 manifestPlaceholders
容器中 icon
, app_name
的值。
客户的需求不仅仅更改App名称与图标,还需要修改webview
加载地址,欢迎页背景图片等等,具体配置如下图:
注意:新增的配置同样需要在清单文件中添加 meta-data
节点。
我们可以通过 Java 代码获取到 meta-data
节点下 android:value
的值。
一般在 MyApplication
获取节点的值:
ApplicationInfo info = null;
try {
info = this.getPackageManager().getApplicationInfo(getPackageName(), PackageManager
.GET_META_DATA);
int tintColor = info.metaData.getInt("tint_color");
String loadUrl=info.metaData.getString("load_url");
String welcomePath = info.metaData.getString("welcome_bg");
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
注意:设置welcome_bg:"@mipmap/klg_welcome"
,我这里以int welcomeRes = info.metaData.getInt("welcome_bg");
去取值,每次都返回0,但tint_color
的值就正常。按正常思维@mipmap/klg_welcome
返回的是 int
值,后来我换成getString
还真获取到了值:res/mipmap-hdpi-v4/sjyg_welcome.png
。获取到路径值,背景的图片资源就不能直接使用。
那么我们把路径资源转换成int
资源,这里就用到了 Java 的反射。具体代码如下:
Class c = R.mipmap.class;
Field[] fields = c.getFields();
for (Field field : fields) {
if (field.getName().equals(welcomePath.substring(welcomePath.lastIndexOf("/") + 1,
welcomePath.lastIndexOf(".")))) {
this.welcomeBgRes = (int) field.get(c.newInstance());
break;
}
}
截取路径字符串获取图片的【名称】,根据【名称】在【R.mipmap.class】类中查找,找到则返回该属性的值。
这样我们就把不同的配置信息保存到了MyApplication
中,使用的时候直接调用。
还有一种方式在Java代码中可以方便获取到gradle
配置文件的数据:
通过代码:context.getResources().getString(R.string.key);
获取值。
注意通过此方式 strings.xml
文件下不能有同名的 key
属性。不然会报相同资源引用错误。
三、生成APK
如果你想生成所有渠道的包:
Terminal命令输入如下指令:
gradlew assembleRelease
构建成功请在以下目录查看:
如果你想针对某个渠道打包:
方式一:
配置不同渠道基础信息。
方式二:
更改 applicationId
,添加 manifestPlaceholders
集合。
多渠道打包,并不需要更改百度、高德等第三方的key
。
多渠道打包,解决了以往深深的忧伤。
源码地址