v2签名方案出来前的多渠道生成方案
(1)androidManifest.xml 配置 meta-data
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:name=".MyApplication"
>
...
<meta-data android:value="360" android:name="store_name"/>
</application>
代码中获取:
val appInfo = packageManager.getApplicationInfo(
packageName,PackageManager.GET_META_DATA)
//
Log.e("lxm", appInfo.metaData.getString("store_name"))
val activityInfo = packageManager.getActivityInfo(
componentName,PackageManager.GET_META_DATA
)
Log.e("lxm","lxm1 :"+appInfo.metaData.get("store_name"))
Log.e("lxm","lxm2 :"+activityInfo.metaData.getString("store_name"))
效果:
(2)android studio build.gradle下的productFlavors定义渠道号
productFlavors {
//线上的包
dg_online {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "release", BUGLY_APP_VERSION: "1.8.0", BUGLY_APP_CHANNEL: "google play"]
buildConfigField "String", "SERVER_PATH", ""
}
india_online {
}
stock_online {
}
}
优势:方便灵活,可以根据自身的需求配置不同的渠道执行不同的逻辑;
劣势:打包速度过慢
(3)META-INF目录下添加空文件,用空文件的名称来作为渠道的唯一标识
v2之前在META-INF下添加文件是不需要重新签名应用的,这样会节省不少打包的时间,从而提高打渠道包的速度
实现原理
Android应用安装包apk文件其实是一个压缩文件,可以将后缀修改为zip直接解压。解压安装文件后会发现在根目录有一个META-INF目录。如果在META-INF目录内添加空文件,可以不用重新签名应用。因此,通过为不同渠道的应用添加不同的空文件,可以唯一标识一个渠道。这种打包方式,只需要在原来的包的基础上复制一个apk,不需要重新签名,可以实现秒生成渠道包
实现步骤:
准备条件:正常的apk包
(a)在META-INF中添加一个使用渠道号命名的空文件,向META-INF/uuchannel_渠道key 文件夹写入一个空文件
//部分代码
empty_channel_file = "META-INF/uuchannel_{channel}".format(channel = target_channel)
zipped.write(src_empty_file, empty_channel_file)
(b)代码中获取渠道字段
/**
* 从apk中获取版本信息
*
* @param context
* @param channelKey
* @return
*/
private static String getChannelFromApk(Context context, String channelKey) {
long startTime = System.currentTimeMillis();
//从apk包中获取
ApplicationInfo appinfo = context.getApplicationInfo();
String sourceDir = appinfo.sourceDir;
//默认放在meta-inf/里, 所以需要再拼接一下
String key = "META-INF/" + channelKey;
String ret = "";
ZipFile zipfile = null;
try {
zipfile = new ZipFile(sourceDir);
Enumeration entries = zipfile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName();
if (entryName.startsWith(key)) {
ret = entryName;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (zipfile != null) {
try {
zipfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
String channel = "";
if (!TextUtils.isEmpty(ret)) {
String[] split = ret.split("_");
if (split != null && split.length >= 2) {
channel = ret.substring(split[0].length() + 1);
}
} else {
channel = DEFAULT_CHANNEL;
}
ToastUtils.showLong("lxm channel:"+channel);
return channel;
}
优势:打包速度很快,很方便;
劣势:不够灵活,不能灵活的配置不同的渠道不同的业务逻辑, app读取效率不是很高。需要初始化zip对象;
(5) Android Apk 动态写入数据方案
原理:apk(zip)文件的格式
apk 默认情况下没有comment,所以 comment length的short 两个字节为 0,我们需要把这个值修改为我们的comment的长度,然后把comment追加到后边
实现步骤:
条件:apk包(a.apk) ,渠道key(360) 或者一组渠道key
(a)判断apk文件是否 comment内容
默认情况下是没有comment,先拷贝新的渠道apk文件(和原来apk只是名称区分a_360.apk)
(b)获取新增的comment内容: 渠道key 的byte数组
(c)修改apk文件:
apk 最后两个字节是short ,comment length 是 0,需要重写实际的长度,先定位到 最后两个字节,重写 comment length ,在 write 新增的comment内容
(d)从文件中读取渠道
效果:
当v2 默认打开时:测试安装显示未通过v2签名认证
对zip动态写入数据方案详情见渠道包快速生成方案
下一节介绍v2签名方案和美团的多渠道打包方案walle