因此我们最终选择了AndFix作为我们的开源方案。具体的AndFix集成方式可参考github中AndFix的介绍
这里简单介绍一下具体的继承流程 (1)在App的Application的onCreate方法中执行AndFix的初始化操作; (2)判断服务器端是否有可更新的热修复差异包 (3)若无则直接退出,若有则下载并执行修复动作 (4)修复完成之后删除下载的补丁差异包 (5)在判断服务器端是否有可更新的补丁包的时候可添加灰度,如版本,渠道,用户等,实现对补丁包定制化的修复
另外需要说明的是:若一个版本中存在着多个bug,则一般的都是让后一个补丁包覆盖前一个补丁包,并删除前一个补丁包,简单来说就是对于每一个版本至多有一个补丁包。
最后贴上App端AndFix的实现源码:
/**
- Created by aaron on 2016/3/7.
- 主要用于实现热修复逻辑
- 采用阿里巴巴开源框架-andfix
*/
public class AndfixManager {
public static final String TAG = AndfixManager.class.getSimpleName();
// AndfixManager单例对象
private static AndfixManager instance = null;
// 补丁文件名称
public static final String PATCH_FILENAME = “/patchname.apatch”;
public static PatchManager patchManager = null;
private AndfixManager() {}
/**
- 线程安全之懒汉模式实现单例模型
- @return
*/
public static synchronized AndfixManager getInstance() {
return instance == null ? new AndfixManager() : instance;
}
/**
- 执行andfix初始化操作
*/
public static void init(Context mContext) {
if (mContext == null) {
L.i(“初始化热修复框架,参数错误!!!”);
return;
}
patchManager = new PatchManager(mContext);
// 初始化patch版本,这里初始化的是当前的App版本;
patchManager.init(VersionUtils.getVersionName(mContext));
// 加载已经添加到PatchManager中的patch
patchManager.loadPatch();
downLoadAndAndPath(mContext);
}
/**
- 请求服务器获取补丁文件并加载
*/
public static void downLoadAndAndPath(final Context mContext) {
// 请求服务器获取差异包
ExtInterface.GetShContent.Request.Builder request = ExtInterface.GetShContent.Request.newBuilder();
// 获取本地保存的补丁包版本号
final String patchVersion = AndfixSp.getPatchVersion(mContext);
L.i(TAG, “patchVersion:” + patchVersion);
if (!TextUtils.isEmpty(patchVersion)) {
request.setShVersion(patchVersion);
} else {
request.setShVersion(“0”);
}
NetworkTask task = new NetworkTask(Cmd.CmdCode.GetShContent_SSL_VALUE);
task.setBusiData(request.build().toByteArray());
NetworkUtils.executeNetwork(task, new HttpResponse.NetWorkResponse() {
@Override
public void onSuccessResponse(UUResponseData responseData) {
if (responseData.getRet() == 0) {
try {
ExtInterface.GetShContent.Response response = ExtInterface.GetShContent.Response.parseFrom(responseData.getBusiData());
// 若返回成功,则更新脚本下载补丁包
if (response.getRet() == 0) {
ByteString zipDatas = response.getContent();
// 数据解压缩
byte[] oriDatas = GZipUtils.decompress(zipDatas.toByteArray());
String patchFileName = mContext.getCacheDir() + PATCH_FILENAME;
L.i(TAG, “patchFileName:” + response.getShVersion());
// 将byte数组数据写入文件
boolean boolResult = getFileFromBytes(patchFileName, oriDatas);
// 写入文件成功则加载
if (boolResult) {
patchManager.removeAllPatch();
patchManager.addPatch(patchFileName);
// 保存补丁版本号
AndfixSp.putPatchVersion(mContext, response.getShVersion());
// 删除补丁文件
File files = new File(patchFileName);
if (files.exists()) {
files.delete();
}
}
} else {
// -1 请求失败
// 1 请求成功,但是没有更新版本的脚本
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onError(VolleyError errorResponse) {
}
@Override
public void networkFinish() {
}
});
}
/**
- 根据数组获取文件
- @param path
- @param oriDatas
*/
public static boolean getFileFromBytes(String path, byte[] oriDatas) {
boolean result = false;
if (TextUtils.isEmpty(path)) {
return result;
}
if (oriDatas == null || oriDatas.length == 0) {
return result;
}
try {
FileOutputStream fos = new FileOutputStream(path);
fos.write(oriDatas);
最后附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总)
面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验,下面这份PDF是我翻阅了差不多1个月左右一些Android大博主的博客从他们那里取其精华去其糟泊所整理出来的一些Android的核心知识点, 全部都是精华中的精华,我能面试到现在资深开发人员跟我整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。
这份PDF囊括了JVM,Java集合,Java多线程并发,Java基础,生命周期,微服务, 进程,Parcelable 接口,IPC,屏幕适配,线程异步,ART,架构,Jetpack,NDK开发,计算机网络基础,类加载器,Android 开源库源码分析,设计模式汇总,Gradle 知识点汇总…
由于篇幅有限,就不做过多的介绍,大家请自行脑补
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
码分析,设计模式汇总,Gradle 知识点汇总…
由于篇幅有限,就不做过多的介绍,大家请自行脑补
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!