前段时间后端的同学比较有空,所以他先做了渠道包的方案。
- V1的签名,在META-INF目录下添加空文件(考虑到游戏也可能会在
ZIP Comment
) - V2的签名,就参考美团的方案(增加一个自定义的key,不会和游戏的方案冲突)
我这边作为SDK,也要支持两种方案,因为游戏两种签名方案都可以使用。当时在另外一个项目中写代码,被中断了一下。自己建了一个紧急任务,花了半天时间,给写出来了。但是当时觉得性能不好,所以留了一个TODO。
最后有空了,再回头去看这个问题。
这次做的这个优化,效果很好(平均获取时间400ms->4ms)。但是没什么技术难度,但是或许以后有小伙伴会遇到类似的问题,我也整理一下,把思路放上来提供参考。
这次的优化主要是两个点:
把 ZipInputStream 替换为 ZipFile
ZipInputStream zis = null;
zis = new ZipInputStream(new FileInputStream(apkFile));
ZipEntry temp;
while ((temp = zis.getNextEntry()) != null) {
if (!temp.isDirectory()) {
// If this apk too big?
if (temp.getName().startsWith(v1_key)) {
return temp.getName().replace(v1_key, "");
}
}
}
ZipFile zipFile = new ZipFile(apkFile);
Enumeration e = zipFile.entries();
ZipEntry entry;
while (e.hasMoreElements()) {
entry = (ZipEntry) e.nextElement();
if (entry.getName().startsWith(v1_key)) {
return entry.getName().replace(v1_key, "");
}
}
ZipInputStream和ZipFile的读取效率差别不小,几乎是一个数量级。修改之前的读取时间是400ms,修改之后就变成30ms了。(apk:400M phone:neuxs5 system:aosp-android6)
获取PackageManager中的lastUpdateTime,判断是否发生了覆盖安装
public static long getPackageLastUpdateTime(Context context) {
String name = context.getPackageName();
long time = 0;
try {
time = context.getPackageManager().getPackageInfo(name, 0).lastUpdateTime;
} catch (Exception e) {
e.printStackTrace();
}
return time;
}
这里用了 lastUpdateTime
来判断是否被覆盖安装。
若未被覆盖安装,从SharedPreferences获取渠道信息。这里把平均时间从30ms降到4ms。
(本文同步于nanny,部分文字有出入请勿见怪)
玩~