Android的增量更新
随着现在移动端的不断普及,移动端逻辑越来越复杂,对移动端APP的要求也越来越高,所以对于一个没有用户的量APP,最重要的是用户。而一个对于一个有用户量的APP来说,最重要的是留住客户,那么对于这样的APP来说,用户体验是他们最关心的。
所以今天要说的就是比较流行的几个关于APP升级的问题,因为APP升级是一个比较头疼的事,一般用户不愿意进行版本升级,因为升级又耗时又费力,有可能费钱,比如说你在没有wifi的情况下。但是对于企业来说,一款APP的不断完善,需要一个过程的积累,所以为了解决这一矛盾,就需要在版本升级上下一些功夫了。
- 什么是增量更新
- APP升级以及更新的几种方式
- 增量更新的优势
- 增量更新的流程
什么是增量更新
相信大家都见过在应用市场省流量更新软件,一个几百M的软件可能只需要下载一个20M的增量包就能完成更新。那么它是如何做的呢?
APP升级以及更新的几种方式
- 传统的APP版本更新
从服务器下载新的安装包,进行版本更新
- 增量更新
形如传统APP更新,拆分出新版本和旧版本的不同之处,生成patch包,从服务器下载相应的patch包,和旧版本APP合成新版本的APP
- 热修复
从服务器下载相应的dex包,进行部分代码的修复
- 插件化更新
只能实现部分更新
增量更新的优势
使得更新包更小,下载更快、省流量,使用户更容易的接受这种方式
增量更新的流程
用户手机上安装着某个应用,下载了增量包,手机上的apk和增量包合并形成新的包,然后再次安装(注意这个过程是要重新安装的,当然部分应用市场有root权限你可能感知不到)。
- 从用户手机上提取当前安装的APP文件
- 通过新版本APK和旧版本APP生成一个增量包
- 用户从服务器下载增量包
- 增量包与当前安装APP合并,生成新版本的APP
- 重新安装
1、从用户手机上提取当前安装的APP文件
public class ApkExtract {
public static String extract(Context context) {
context = context.getApplicationContext();
ApplicationInfo applicationInfo = context.getApplicationInfo();
String apkPath = applicationInfo.sourceDir;
Log.d("hongyang", apkPath);
return apkPath;
}
}
2、通过新版本APK和旧版本APP生成一个增量包
生成APP增量包一般放在服务器端,因为放在服务器端需要服务器数据库进行记录,并且也更加方便
这个其实就是利用工具做二进制的一个bsdiff和bspatch了。
网址:
http://www.daemonology.net/bsdiff/
下载地址:
http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz
ok,假设到这里,不管你使用何种手段,咱们已经有了bsdiff和bspacth,下面演示下这个工具的使用:
首先我们准备两个apk,old.apk和new.apk,你可以自己随便写个项目,先运行一次拿到生成的apk作为old.apk;然后修改些代码,或者加一些功能,再运行一次生成new.apk;
- 生成增量文件
./bsdiff old.apk new.apk old-to-new.patch
- 增量文件和old.apk合并成新的apk
./bspatch old.apk new2.apk old-to-new.patch
这样就生成一个new2.apk
那么怎么证明这个生成的new2.apk和我们的new.apk一模一样呢?
我们可以查看下md5的值,如果两个文件md5值一致,那么几乎可以肯定两个文件时一模一样的(不要跟我较真说什么碰撞可以产生一样的md5的值~~)。
aaa:bsdiff-4.3 zhy$ md5 new.apk
MD5 (new.apk) = 0900d0d65f49a0cc3b472e14da11bde7
aaa:bsdiff-4.3 zhy$ md5 new2.apk
MD5 (new2.apk) = 0900d0d65f49a0cc3b472e14da11bde7
3、用户从服务器下载增量包
简单文件下载操作,自行百度
4、增量包与当前安装APP合并,生成新版本的APP
此时需要用到JNI,使用本地方法调用C库方法,C方法开源代码中已给出
5、重新安装
public static void install(Context context, String apkPath) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.fromFile(new File(apkPath)),
"application/vnd.android.package-archive");
context.startActivity(i);
}
源码:
https://github.com/JsonNan/AndroidPatchUpdate
写这篇文章的目的更多的是为了总结
相关文章可参考鸿洋大神