Android 增量更新和升级
在年初的时候,尝试了一把热修复技术,当时选择的是阿里的andfix,使用起来也很简单,这里就不在多少,如果你对andfix有兴趣请链接:点击打开链接。虽然网上将热修复的文章很多,不过我还是想说原理,然后配合代码,我想这样大家理解更加深刻。
原理
热修复(打补丁)
| 拷贝资源 | 拷贝旧版本APK以及新版本APK到SD卡。为了后面进行生成差分包 |
| 安装旧版本APK | 安装旧版本的APK |
| 生成补丁 | 生成差分包。这个实际上应该是在服务端完成 |
| 打补丁 | 通过差分包及旧版本APK生成新版本APK |
| 安装新版本APK | 安装生成的新版本APK |
| 获取某个应用的APK安装文件 | 在真正的增量更新过程中,旧版本Apk应该从/data/app底下获取,拷贝到SD卡,进行打补丁。当然,也可以不拷贝,直接使用该路径。 |
为了方便,我们就在本地放两个本地,为了方便讲解,我们先定义4个变量。
String srcDir = Environment.getExternalStorageDirectory().toString() + "/DaemonProcess-1.apk"; String destDir1 = Environment.getExternalStorageDirectory().toString() + "/DaemonProcess-2.apk"; String destDir2 = Environment.getExternalStorageDirectory().toString() + "/DaemonProcess-3.apk"; String patchDir = Environment.getExternalStorageDirectory().toString() + "/DaemonProcess.patch";
String appDir = getPackageManager().getApplicationInfo(packageName, 0).sourceDir;
destDir1:新版本的apk路径。
destDir2:新版本的apk路径。通过差分包+旧版本APK合成新版本APK。
patchDir:差分包。通过旧版本APK+新版本APK生成差分包。
public class DiffUtils {
static DiffUtils instance;
public static DiffUtils getInstance() {
if (instance == null)
instance = new DiffUtils();
return instance;
}
static {
System.loadLibrary("ApkPatchLibrary");
}
/**
* native方法 比较路径为oldPath的apk与newPath的apk之间差异,并生成patch包,存储于patchPath
*/
public native int genDiff(String oldApkPath, String newApkPath, String patchPath);
}
合成新包Native方法:
public class PatchUtils {
static PatchUtils instance;
public static PatchUtils getInstance() {
if (instance == null)
instance = new PatchUtils();
return instance;
}
static {
System.loadLibrary("ApkPatchLibrary");
}
/**
* native方法 使用路径为oldApkPath的apk与路径为patchPath的补丁包,合成新的apk,并存储于newApkPath
*/
public native int patch(String oldApkPath, String newApkPath, String patchPath);
}
这里用到了一个ndk,如果有需要了解如何生成动态库文件的可以访问下面的点击打开链接
private class CopyTask extends AsyncTask<String, Void, Integer> {
@Override
protected Integer doInBackground(String... params) {
for (int i = 0; i < params.length; i += 2) {
try {
File file = new File(params[i]);
if (!file.exists())
FileUtils.createFile(file);
InputStream is;
OutputStream os = new FileOutputStream(params[i]);
is = getAssets().open(params[i + 1]);
byte[] buffer = new byte[1024];
int length = is.read(buffer);
while (length > 0) {
os.write(buffer, 0, length);
length = is.read(buffer);
}
os.flush();
is.close();
os.close();
} catch (Exception e) {
handler.obtainMessage(1).sendToTarget();
return null;
}
}
handler.obtainMessage(0).sendToTarget();
return null;
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
loadding.setVisibility(View.GONE);
}
}
2,合成新的apk(jni会自动判断是否合成成功)
private class PatchTask extends AsyncTask<String, Void, Integer> {
@Override
protected Integer doInBackground(String... params) {
try {
int result = PatchUtils.getInstance().patch(srcDir, destDir2, patchDir);
if (result == 0) {
handler.obtainMessage(4).sendToTarget();
return WHAT_SUCCESS;
} else {
handler.obtainMessage(5).sendToTarget();
return WHAT_FAIL_PATCH;
}
} catch (Exception e) {
e.printStackTrace();
}
return WHAT_FAIL_PATCH;
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
loadding.setVisibility(View.GONE);
}
}
3,安装新的apk
private void install(String dir) {
String command = "chmod 777 " + dir;
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec(command); // 可执行权限
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + dir), "application/vnd.android.package-archive");
startActivity(intent);
}
服务端工具以及源码位于Server目录下。目前只在Linux64位的系统下编译,其他系统大家可自行编译。Linux下的可直接修改makefile,windows下可用VC编译。
Diff工具:生成差分包
<!--命令 oldApk newApk patch--> ./linux-x86_64/Diff DaemonProcess-1.apk DaemonProcess-2.apk dp.patch
Patch工具:合并
<!--命令 oldApk newApk patch--> ./linux-x86_64/Patch DaemonProcess-1.apk DaemonProcess-3.apk dp.patch
代码地址:点击打开链接
Android 增量更新和升级的更多相关文章
- Android 增量更新(BSDiff / bspatch)
Android 增量更新 BSDiff / bspatchhttp://www.daemonology.net/bsdiff/android的代码目录下 \external\bsdiff bsdiff ...
- Android 增量更新研究
Android 增量更新实例(Smart App Updates) http://blog.csdn.net/duguang77/article/details/17676797 Android AP ...
- 一句话的Android增量更新框架(增量更新)
转自:http://www.jianshu.com/p/a9ec8fa780e2 Android应用更新要使用完整的新版本Apk安装,增量更新则是提供一个新旧版本偏差数据的patch包供应用下载,然后 ...
- Android 增量更新实例(Smart App Updates)
原地址:http://my.oschina.net/liucundong/blog/160436 官方说明 实现原理 实现 (1)生成差异包 (2)使用旧apk+差异包,在客户端合成新apk 注意事项 ...
- Android 增量更新
title: Android NDK之增量更新 1.增量更新使用到的库bsdiff和bzip2 bsdiff库是一个开源的二进制差分工具,通过对比Apk的二进制,从而进行差分包的生成. bsdiff库 ...
- Android 增量更新完全解析 是增量不是热修复(转)
转自:http://blog.csdn.net/lmj623565791/article/details/52761658 本文在我的微信公众号:鸿洋(hongyangAndroid)首发. 转载请标 ...
- android 增量更新原理
原理如下:服务器端设计增量表,记录数据操作顺序id,和增删改查信息.在进行数据库表操作的时候同时进行将信息保存在增量表. android客户端在请求的时候上传最后保存的id.服务端判断最后的id,返回 ...
- Android增量更新
http://blog.csdn.net/tu_bingbing/article/details/8538592 (转)
- Android studio使用增量更新进行版本升级
今天将Android Studio更新了一下,特此记录一下升级过程,以后可能还会用得着. 首先通过菜单栏进入 Help --> Check for update 查看下当前版本是否需要更新.事实 ...
随机推荐
- 【AIM Tech Round 4 (Div. 2) D Prob】
·题目:D. Interactive LowerBound ·英文题,述大意: 有一个长度为n(n<=50000)的单链表,里面的元素是递增的.链表存储在一个数组里面,给出长度n.表 ...
- 如何在Google上下载高清原图
在我们学习和生活中常常一些高清图片作为相关的素材,比如制作PPT.写博文.制作视频都需要大量图片.我们常常会在百度上下载一些图片,但是百度上提供的图片存在很多问题:存在水印.清晰度不够等.而Googl ...
- Linux学习之CentOS(十)----Linux 的账号与群组
Linux 的账号与群组 管理员的工作中,相当重要的一环就是『管理账号』啦!因为整个系统都是你在管理的, 并且所有一般用户的账号申请,都必须要透过你的协助才行!所以你就必须要了解一下如何管理好一个服务 ...
- JVM基础
1.基础 JDK 将java文件编译成class文件 JRE 包含JVM JVM可以进行内存管理 利用JDK(调用JAVA API)开发了属于我们自己的JAVA程序后,通过JDK中的编译程序(j ...
- super 关键字
- 特殊权限 SUID、SGID、Sticky
摘录之----------QuintinX 一. 前提 本篇主要讲解SUID, SGID, Sticky三个权限的基本原理和应用. 为什么要使用特殊权限? 比如系统中假如有超过四类人然而每一类人都需要 ...
- ionic3-ng4学习见闻--(多环境方案)
搜了很久,很难找到一个详细入微,开箱即用的方案. 于是我 百折不挠的,搞出来一个,也不知道是不是最完美的方案,有什么可以优化的地方可以指出,谢谢. 首先, 1.项目目录下(与src平级),新增conf ...
- Web压力测试和手机App测试
总纲:认识测试关系和目标http://blog.csdn.net/superxgl/article/details/27189631 一.web测试和App服务端测试 软件安装 建议安装loadrun ...
- c++ 深入理解数组
阅读前提:你得知道啥是数组. 本文需要弄清楚的问题如下: 1,数组作为函数参数,传入的是值,还是地址? 2,数组作为函数参数,数组的长度能否确定? 解决如下 1,数组作为函数参数,传入的是地址.因为数 ...
- electron应用以管理员权限启动
最近在用electron开发PC桌面应用,其中有个需求就是整个应用以管理员权限启动.很头痛,各种google,baidu. 最后终于解决了,可以分为三个步骤,做个总结分享. 一.如果没有manifes ...