AndFix
AndFix 是阿里巴巴开源的 Android 应用热修复工具,帮助 Anroid 开发者修复应用的线上问题。Andfix 是 “Android hot-fix” 的缩写。支持 Android 2.3 - 6.0,ARM 和 x86 架构,dalvik 运行时和 art 运行时。AndFix 的分支是 .apatch 文件。
GitHub地址 : https://github.com/alibaba/AndFix
原理图:
使用概述
1. 添加依赖
dependencies { compile 'com.alipay.euler:andfix:0.3.1@aar'}
2 . 尽可能早的加载补丁
package com.dyk.andfixtest;import android.app.Application;import android.content.pm.PackageManager;import com.alipay.euler.andfix.patch.PatchManager;/**
* Created by dyk on 2016/3/24.
*/public class MyApplication extends Application {
private static MyApplication instance; private PatchManager patchManager; public static MyApplication getInstance(){ return instance;
} @Override
public void onCreate() { super.onCreate();
instance = this; // 初始化patch管理类
patchManager = new PatchManager(this);
String appVersion = null; try {
appVersion = getPackageManager().getPackageInfo(getPackageName(),0).versionName; // 初始化patch版本
patchManager.init(appVersion); // 加载已经添加到PatchManager中的patch
patchManager.loadPatch();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
} public PatchManager getPatchManager() { return patchManager;
}
}
每次appVersion变更都会导致所有补丁被删除,如果appversion没有改变,则会加载已经保存的所有补丁。
3. 加载新补丁
MyApplication.getInstance().getPatchManager().addPatch(patchPath);
详细使用教程
1 . 添加依赖
2. 尽可能早的加载补丁
3. 修复bug,生成没有bug的apk文件
4. 对比新旧apk生成.apatch补丁文件
5. 加载新补丁,修复bug
前两步在使用概述中已经说明,不在赘述。修复bug,生成新apk也和正常一样。这里注意一个地方:生成新旧apk要使用同一个.jks签名文件。下面是一个示例
从一个Demo开始
制造bug
下面的代码假设在waitFix()里存在bug(Log.i(TAG, “waitFix bug”),我们目标是不发布新版本,改变这行log)
package com.dyk.andfixtest;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.View;import android.view.Window;import java.io.IOException;public class MainActivity extends Activity {
private static final String TAG = "AndFix"; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
findViewById(R.id.showLogBtn).setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
waitFix();
}
});
findViewById(R.id.fixBtn).setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
String patchPath = Environment.getExternalStorageDirectory()+"/tmp/first.apatch"; try {
MyApplication.getInstance().getPatchManager().addPatch(patchPath);
Log.i(TAG,"fix bug, please reClick");
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG,"error:"+e.toString());
}
}
});
} // 假设待修复的Bug在此方法中
private void waitFix() {
Log.i(TAG,"waitFix bug");
}
}
因为要读取.apatch文件,不要忘了添加限权。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
此时我们签名运行apk,生成bug.apk。
// 已修复private void waitFix() {
Log.i(TAG,"fix bug");
}
修改bug后生成fix.apk。
生成.aptch补丁文件需要一个工具,点我下载。现在打开命令行(cmd),进入从刚下载工具的tools文件夹(我的是D:\Temp\AndFix\AndFix-master\tools,命令行为:d:回车,cd D:\Temp\AndFix\AndFix-master\tools)。将bug.apk、fix.apk和签名文件放入tools文件夹下。输入命令
apkpatch -o D:\Temp\AndFix\output -k AndFix.jks -p admin888 -a 亚洲 -e admin888 -f fix.apk -t bug.apk
字段说明:
-o <output> : 输出目录-k <keystore>: 打包所用的keystore-p <password>: keystore的密码-a <alias>: keystore 用户别名-e <alias password>: keystore 用户别名密码-f <new.apk> :新版本-t <old.apk> : 旧版本
看见如上提示即生成.apatch文件成功。进入输出目录(-o 后面)。可以看到一个smail文件夹、diff.dex和一个.apatch文件。经常反编译别人apk的同学一定对smail文件夹不陌生。可以查看到代码,可惜才疏学浅看不懂.smail文件。这里我们要用到的是.apatch文件。
1. 更改.apatch文件名为first.apatch。
2. 安装bug.apk,真是个不吉利的名字。
3. 将first.apatch放入MainActivity里的patchPath路径下(我这里是/tmp/)。
4. 运行bug.apk
依次点击showLogBtn、fixBtn、showLogBtn。Log输出如下
可以看到Log输出已经改变,这也意味着带有Bug的方法被成功修复。
多次打补丁
如果本地保存了多个补丁,那么AndFix会按照补丁生成的时间顺序加载补丁。具体是根据.apatch文件中的PATCH.MF的字段Created-Time。
混淆
-keep class * extends java.lang.annotation.Annotation-keepclasseswithmembernames class * {
native <methods>;
}
探索
1. 修改first.apatch后缀名为.zip
2. 解压文件
打开META-INF中的文件PATCH.MF,可以看到如下内容
Manifest-Version: 1.0Patch-Name: fixCreated-Time: 25 Mar 2016 08:28:00 GMTFrom-File: fix.apkTo-File: bug.apkPatch-Classes: com.dyk.andfixtest.MainActivity_CFCreated-By: 1.0 (ApkPatch)
可以发现Patch-Classes就是被改动过的文件,后面还加个_CF(CrossFire ?)。
使用dex2jar反编译classes.dex
1. 下载dex2jar和jd-gui,点我下载
2. 将classes.dex文件复制到dex2jar解压目录
3. 命令行进入dex2jar解压目录
4. 输入命令:d2j-dex2jar classes.dex
经过四招还我漂漂拳后,可以在dex2jar解压目录下发现classes-dex2jar.jar这么一个文件。
使用jd-gui打开classes-dex2jar.jar
package com.dyk.andfixtest;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import com.alipay.euler.andfix.annotation.MethodReplace;public class MainActivity_CF extends Activity{
private static final String TAG = "AndFix"; @MethodReplace(clazz="com.dyk.andfixtest.MainActivity", method="waitFix") private void waitFix()
{
Log.i("AndFix", "fix bug");
} protected void onCreate(Bundle paramBundle)
{ super.onCreate(paramBundle);
requestWindowFeature(1);
setContentView(2130968601);
findViewById(2131492944).setOnClickListener(new MainActivity.1(this));
findViewById(2131492943).setOnClickListener(new MainActivity.2(this));
}
}
可以发现.patch只是差异文件,这里给需要替换的方法添加了一个指定class和method的注解@MethodReplace(clazz="com.dyk.andfixtest.MainActivity", method="waitFix")
。客户端sdk得到补丁文件后根据注解寻找需要替换的方法。最后由JNI层完成方法的替换。
AndFix的更多相关文章
- Android热修复AndFix
热修复主要用来修复代码.修复bug.添加独立的功能,他的原理主要是操作PathClassLoader.DexClassLoader. PathClassLoader是类加载器,DexClassLoad ...
- 支付宝Andfix 原理解析
支付宝Andfix 原理解析 使用参考地址: http://blog.csdn.net/qxs965266509/article/details/49802429 原理参考地址: http://blo ...
- 阿里资深工程师分享支付宝热补丁技术—— AndFix原理
本文由嵌入式企鹅圈原创团队成员.阿里资深工程师Hao分享. 上次我们介绍了用dexposed方案实施热补丁的原理,它本质上就是hook要修改的函数,这样一来在正式版本发布时就不能直接拿热补丁的代码集成 ...
- AndFix热修复 —— 实战与源码解析
当你的应用发布后第二天却发现一个重要的bug要修复,头疼的同时你可能想着赶紧修复重新打个包发布出去,让用户收到自动更新重新下载.但是万事皆有可能,万一隔一天又发现一个急需修复的bug呢?难道再次发布打 ...
- Android热修复实践应用--AndFix
一直关注App的热修复的技术发展,之前做的应用也没用使用到什么热修复开源框架.在App的热修复框架没有流行之前,做的应用上线后发现一个小小的Bug,就要马上发一个新的版本.我亲身经历过一周发两个版本, ...
- 《android基于andFix的热修复方案》实战篇
有篇文章说的比较简洁,大家可以参考下:AndFix使用说明 下面说说实际使用中遇到的问题 1:如何继承到gradle项目中 dependencies { compile 'com.alipay.eul ...
- 《android基于andFix的热修复方案》思路篇
1:需求背景 项目上线之后,发现BUG需要修复(比如安卓兼容性等测试难以发现的问题),频繁的更新影响用户体验 2:方案要求 静默下载,耗费流量少,打完补丁后立刻生效,不用重启apk 3:解决思路 3. ...
- 阿里开源的热补丁框架AndFix使用教程
阿里巴巴推出的AndFix框架 首次给出大家这个框架的地址:https://github.com/alibaba/AndFix 对源码比较感兴趣的同学们可以自行研究代码 AndFix原理介绍 AndF ...
- 安卓热修复之AndFIX
我致力于最新的前沿安卓技术分析和使用教学,不打算将很多很深的东西,因为有多少人愿意沉下你的心境去学习难点?我一般只会简单提及.文字错漏在所难免还希望同学们喜欢 热修复介绍 热修复是什么? 如果你一个项 ...
随机推荐
- 邮件报警(postfix)
postfix是Wietse Venema在IBM的GPL协议之下开发的MTA(邮件传输代理)软件.postfix是Wietse Venema想要为使用最广泛的sendmail提供替代品的一个尝试.在 ...
- Python笔记001-----简介及常用的库
1.Python是一种解释性语言,大部分代码要比编译型语言(如C++,java等)运行要慢点多.2.对于高并发,多线程的应用程序而言,Python并不是理想语言,python有全局解释器锁(Globa ...
- 客户端putty xshell连接linux中vim不能正常使用小键盘的问题
在putty或xshell上用vi/vim的时候,开NumLock时按小键盘上的数字键并不能输入数字,而是出现一个字母然后换行(实际上是命令模式上对应上下左右的键). 解决方法: putty:选项Te ...
- linux下磁盘占用达到100%了,找不到哪些大文件耗尽了磁盘
Linux下的根分区使用率100%,但是查看/分区下的目录都不大,没有占用满,这该怎么处理? 重启是肯定有效的,目前处理情况:重新restart应用后,空间释放出来 1.lsof | grep del ...
- Audio Unit 基础
如图所示,所有 iOS 音频技术都是基于 audio units.此处显示的更高级别的技术,如 Media Player,AV Foundation,OpenAL,AudioToolbox,是对 au ...
- Cypher查询语言--Neo4j-MATCH(二)
目录 Match 相关节点 接出关系Outgong relationship 定向关系和标识符 通过关系类型匹配 通过关系类型匹配和使用标识符 带有特殊字符的关系类型 多重关系 可变长度的关系 在可变 ...
- Mysql基础安装,初视篇
mysql 跟所有的数据库软件一样分为 服务端和客户端: 下载:在官网里面选择 download 社区版本,mysql,社区版本 安装: win环境下: 第一步:解压文件出来 第二步:在bin文件下 ...
- Laravel 5.4.36 session 没有保存成功问题
session使用注意点 工作中使用的是session默认的文件缓存 在使用过发现 session()->put("key","values") 发 ...
- RandomAccess接口的使用
RandomAccess在类Collections的shuffle()方法中的使用:(jdk源码如下) /** * Randomly permute the specified list using ...
- BZOJ 1022: [SHOI2008]小约翰的游戏John [SJ定理]
传送门 $anti-nim$游戏,$SJ$定理裸题 规定所有单一游戏$sg=0$结束 先手必胜: $1.\ sg \neq 0,\ 某个单一游戏sg >1$ $2.\ sg = 0,\ 没有单一 ...