Android热修复实践应用--AndFix
一直关注App的热修复的技术发展,之前做的应用也没用使用到什么热修复开源框架。在App的热修复框架没有流行之前,做的应用上线后发现一个小小的Bug,就要马上发一个新的版本。我亲身经历过一周发两个版本,真的折腾用户的节奏~~所以,要开始考虑引入热修复。下面记录使用开源框架阿里巴巴的AndFix过程。
实现的原理
这里说的不是热修复怎么实现修bug的原理,这里说的是怎么使用AndFix。如果你想了解更多的andFix实现原理,你可以参考下面的文章:
- https://github.com/alibaba/AndFix (AndFix的官网)
- http://blog.csdn.net/lmj623565791/article/details/49883661 (Android大神鸿洋的Bolg文章)
- 应用启动的时候,在 onCreate() 方法中获取友盟的在线参数来判断当前的应用版本是否有补丁需要下载,有则通过ThinDonloadManager来下载到SD下并且通过使用AndFix来加载到应用中。
- 使用极光推送消息到该应用的版本需要下载补丁,如果应用收到了消息后,应用判断当前的版本是否需要下载补丁。如果应用没有收到消息的通知,则下次启动App的时候,获取友盟在线参数来判断是否需要下载补丁。
步骤
在gradle文件中增加相应的依赖。这里我使用thindownlaodmanager来下载补丁,使用极光推送来推送自定义消息下载补丁通知,使用友盟在线参数来获取补丁包的信息。也许你会问为了修复一个补丁而增加这么多的依赖,值得吗?我认为还可以吧,因为我的项目一般会使用到这些。
AndFix的引入是: compile 'com.alipay.euler:andfix:0.3.1@aar'
导入AndFix的so库文件以及极光推送的so库文件;
极光推送集成参考文档:http://docs.jpush.io/client/android_sdk/
注意:导入AndFix的so文件时,可以先阅读这下个:https://github.com/zhonghanwen/AndFix-Ndk-Build-ADT- 接着,集成友盟在线参数
参考官方文档:http://dev.umeng.com/online-parameters/android-doc/intergration
- 接着,集成友盟在线参数
配置友盟在线参数的参数以及推光推送自定义的内容
友盟在线参数
极光推送自定义消息(自定义消息有长度限制,所以补丁的下载url写成拼接形式:站点+下载资源名称)
定义相对应的Bean
在启动的自定义Application类进行初始化工作(AndFix、极光的初始化)
在程序的入口类进行友盟补丁的检测:
private void getUmengParamAndFix() {
//获取友盟在线参数对应key的values
String pathInfo = OnlineConfigAgent.getInstance().getConfigParams(this, UMENG_ONLINE_PARAM);
if (!TextUtils.isEmpty(pathInfo)){
PatchBean onLineBean = GsonUtils.getInstance().parseIfNull(PatchBean.class , pathInfo);
try {
//进行判断当前版本是否有补丁需要下载更新
RepairBugUtil.getInstance().comparePath(this, onLineBean);
} catch (Exception e) {
e.printStackTrace();
}
}
}再加上推送推送的自定义内容的处理:(当推送消息过来的时候应用处于运行状态的时候,程序会处理消息进行下载补丁包)
private WeakHandler mHandler = new WeakHandler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == MSG_WHAT_DOWNLOAD){
String message = (String) msg.obj;
if (TextUtils.isEmpty(message)) return false;
try {
PatchBean bean = GsonUtils.getInstance().parse(PatchBean.class, message);
RepairBugUtil.getInstance().comparePath(MainActivity.this, bean);
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
}); //for receive customer msg from jpush server
private MessageReceiver mMessageReceiver;
public static final String MESSAGE_RECEIVED_ACTION = "com.zhw.andfix.MESSAGE_RECEIVED_ACTION";
public static final String KEY_MESSAGE = "message"; public void registerMessageReceiver() {
mMessageReceiver = new MessageReceiver();
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(MESSAGE_RECEIVED_ACTION);
registerReceiver(mMessageReceiver, filter);
} public class MessageReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
if (MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
String message = intent.getStringExtra(KEY_MESSAGE);
Message msg = new Message();
msg.what = MSG_WHAT_DOWNLOAD;
msg.obj = message;
mHandler.sendMessage(msg);
}
}
}补丁包的生成
- 下载AndFix的补丁生成工具:here
- 生成补丁的文件需要的文件有:原apk文件,修复Bug后生成的新apk,签名文件。
- 在解压apkpatch工具的目录下,打开命令行输入以下命令生成补丁包。
apkpatch -m <apatch_path...> -o <output> -k <keystore> -p <***> -a <alias> -e <***>
- 将生成的补丁放到指定服务器上。(这里我放到了七牛上)
自己测试一下成不成啦~
代码
通过ThinDownloadManager下载补丁包,下载成功后使用AndFix加载补丁包的方法:
public void downloadAndLoad(Context context, final PatchBean bean, String downloadUrl) {
if (mLocalPreferencesHelper == null) {
mLocalPreferencesHelper = new LocalPreferencesHelper(context, SPConst.SP_NAME);
}
Uri downloadUri = Uri.parse(downloadUrl);
Uri destinationUri = Uri.parse(Environment.getExternalStorageDirectory()
.getAbsolutePath() + bean.url);
DownloadRequest downloadRequest = new DownloadRequest(downloadUri)
.setDestinationURI(destinationUri)
.setPriority(DownloadRequest.Priority.HIGH)
.setDownloadListener(new DownloadStatusListener() {
@Override
public void onDownloadComplete(int id) {
// add patch at runtime
try {
// .apatch file path
String patchFileString = Environment.getExternalStorageDirectory()
.getAbsolutePath() + bean.url;
BaseApplication.mPatchManager.addPatch(patchFileString);
Log.d(TAG, "apatch:" + patchFileString + " added."); //复制且加载补丁成功后,删除下载的补丁
File f = new File(patchFileString);
if (f.exists()) {
boolean result = new File(patchFileString).delete();
if (!result)
Log.e(TAG, patchFileString + " delete fail");
}
// mLocalPreferencesHelper.saveOrUpdate(SPConst.IsHavePathDownLoad, false);
} catch (IOException e) {
Log.e(TAG, "", e);
} catch (Throwable throwable) { }
} @Override
public void onDownloadFailed(int id, int errorCode, String errorMessage) {
//下载失败的时候,标注标记位,等下次重新打开应用的时候重新下载
// mLocalPreferencesHelper.saveOrUpdate(SPConst.IsHavePathDownLoad, true);
Log.e(TAG, "onDownloadFailed"); } @Override
public void onProgress(int id, long totalBytes, int progress) {
Log.e(TAG, "progress:" + progress);
}
});
mDownloadManager = new ThinDownloadManager(THREAD_COUNT);
mDownloadManager.add(downloadRequest);
}
判断是否有补丁包需要下载的方法:
public void comparePath(Context context, PatchBean RemoteBean) throws Exception {
String pathInfo = mLocalPreferencesHelper.getString(SPConst.PATH_INFO);
final PatchBean localBean = GsonUtils.getInstance().parseIfNull(PatchBean.class, pathInfo);
//远程的应用版本跟当前应用的版本比较
if (BaseApplication.VERSION_NAME.equals(RemoteBean.app_v)) {
//远程的应用版本跟本地保存的应用版本一样,但补丁不一样,则需要下载重新
/**
*第一种情况:当本地记录的Bean为空的时候(刚安装的时候可能为空)并且远程的Bean的path_v不为空的时候需要下载补丁。
* 第二种情况:当本地记录的path_v和远程Bean的path_v不一样的时候需要下载补丁。
*/
if (localBean == null && !TextUtils.isEmpty(RemoteBean.path_v)
|| localBean.app_v.equals(RemoteBean.app_v) &&
!localBean.path_v.equals(RemoteBean.path_v)) {
downloadAndLoad(context, RemoteBean,
SPConst.URL_PREFIX + RemoteBean.url);
String json = GsonUtils.getInstance().parse(RemoteBean);
mLocalPreferencesHelper.saveOrUpdate(SPConst.PATH_INFO, json);
} /*else {
mLocalPreferencesHelper.saveOrUpdate(SPConst.IsHavePathDownLoad, false);
}*/
}
}
附
项目GitHub地址:https://github.com/zhonghanwen/AndFix-Bad-Practices
Android热修复实践应用--AndFix的更多相关文章
- Android热修复之AndFix使用教程
AndFix的github地址 AndFix 全称Android hot-fix,是alibaba的Android热修复框架,支持Android 2.3到6.0的版本,支持arm与X86系统架构,支持 ...
- 全面了解Android热修复技术
WeTest 导读 本文探讨了Android热修复技术的发展脉络,现状及其未来. 热修复技术概述 热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部 ...
- Android热修复之微信Tinker使用初探
文章地址:Android热修复之微信Tinker使用初探 前几天,万众期待的微信团队的Android热修复框架tinker终于在GitHub上开源了. 地址:https://github.com/ ...
- Android热修复框架汇总整理(Hotfix)
Android平台出现了一些优秀的热更新方案,主要可以分为两类:一类是基于multidex的热更新框架,包括Nuwa.Tinker等:另一类就是native hook方案,如阿里开源的Andfix ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- Android热修复技术总结
https://blog.csdn.net/xiangzhihong8/article/details/77718004 插件化和热修复技术是Android开发中比较高级的知识点,是中级开发人员通向高 ...
- Android热修复技术原理详解
阿里Dexposed -- native解决方案 原理: 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能 他的思想完全来源于Xposed框架,完美诠释 ...
- 深入探索Android热修复技术原理读书笔记 —— 热修复技术介绍
1.1 什么是热修复 对于广大的移动开发者而言,发版更新是最为寻常不过的事了.然而,如果你 发现刚发出去的包有紧急的BUG需要修复,那你就必须需要经过下面这样的流程: 这就是传统的更新流程,步骤十分繁 ...
- 深入探索Android热修复技术原理读书笔记 —— 代码热修复技术
在前一篇文章 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍中,对热修复技术进行了介绍,下面将详细介绍其中的代码修复技术. 1 底层热替换原理 在各种 Android 热修复方案中 ...
随机推荐
- Java Override/Overload
重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变.即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为. 也就是说子类能 ...
- C#调用SQL Server参数过程传参
-SQL SERVER生成测试环境: Create database Test; go USE [Test] GO if OBJECT_ID('Tab2','U') is not null drop ...
- 烂泥:puppet3.7安装与配置
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 有关服务器的自动化管理,这方面以前没有接触过.打算这段时间把这块知识给补上. 现在服务器自动化管理软件,使用最多也最火的就是puppet了. 那么我们今 ...
- Linux 多线程信号量同步
PV原子操作 P操作: 如果有可用的资源(信号量值>0),则此操作所在的进程占用一个资源(此时信号量值减1,进入临界区代码); 如果没有可用的资源(信号量值=0),则此操作所在的进程被阻塞直到系 ...
- 扩展欧几里德算法 cogs.tk 2057. [ZLXOI2015]殉国
2057. [ZLXOI2015]殉国 ★☆ 输入文件:BlackHawk.in 输出文件:BlackHawk.out 评测插件时间限制:0.05 s 内存限制:256 MB [题目描 ...
- POJ 1696 Space Ant 【极角排序】
题意:平面上有n个点,一只蚂蚁从最左下角的点出发,只能往逆时针方向走,走过的路线不能交叉,问最多能经过多少个点. 思路:每次都尽量往最外边走,每选取一个点后对剩余的点进行极角排序.(n个点必定能走完, ...
- GitHub 下载文件夹
工具 TortoiseSVN 步骤 1.打开要下载的项目,选中要下载的文件夹,右键 选择 复制链接地址 2.把链接中的 tree/master 改成 trunk ,(trunk是master分支,可以 ...
- 什么是UV?
转自http://www.cnblogs.com/jenry/p/4083415.html 1.什么是UV? 对于三维模型,有两个最重要的坐标系统,一是顶点的位置(X,Y,Z)坐标,另一个就是UV ...
- Java面向对象编程之异常处理机制
一:Java的异常处理机制的优点: 1:把各种不同情况的异常情况分类,使用JAVA类来表示异常情况,这种类被称为异常类.把各种异常情况表示成异常类,可以充分的发挥类的可扩展性和可重用性. 2:异常流程 ...
- 应用多个icon的对比
在给应用设计图标的时候,可能会遇到这样的需求,应用图标有老版和新版两种,而又想在桌面上同时显示这两个图标以对比效果. 一个应用本身只有一个自己的icon,在AndroidManifest.xml文件中 ...