Android热修复原理和例子
来源:互联网 发布:贵阳网站建设方舟网络 编辑:程序博客网 时间:2024/06/05 14:54
概述:
热修复其实很简单,通俗理解就找到有bug的apk和无bug的apk的差异生成一个.apatch(按照AndFix使用)结尾的文件,通过预先固定的通道从网上下载无bug的代码替换有bug的代码,从而实现bug的修复,最关键的是用户体验好,如果按照正常的流程操作的话需要开发人员修复完bug后打包经过测试人员测试后,上传到多个应用市场;通过热修复的方法就省去了很大的人力物力成本。
1 热修复的原理
Android的类加载器有两种:PathClassLoader和DexClassLoader,两者的父类是BaseDexClassLoader,BaseDexClassLoader的父类是ClassLoader
其中PathDexLoader用来加载系统类和应用类;
DexClassLoader用来加载一些jar、apk、dex文件,其实jar和apk文件实际上加载的都是dex文件
热修复原理:ClassLoader会遍历一个由dex文件组成的数组,然后加载其中的dex文件,我们会把正确的dex(修复过的类所在的dex)文件插入数组的前面,当加载器加载到好 的类文件时候就不会加载有bug的类了,就实现了热修复
2 热修复例子
本案例使用的是阿里的开源热修复框架AndFix
1 首先建立一个App类继承自Application
public class App extends Application { private static final String TAG = "App"; //生成的apatch文件名 public static final String APATCH_PATCH = "jiang.apatch"; private PatchManager mPatchManager; @Override public void onCreate() { super.onCreate(); //初始化 mPatchManager = new PatchManager(this); String appversion=null; try { //这个地方要是用此方法获取versionName appversion= getPackageManager().getPackageInfo(getPackageName(), 0).versionName; Log.i("aaa",""+appversion); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } mPatchManager.init(appversion); //加载apatch mPatchManager.loadPatch(); //apatch文件的目录 String patchFileString = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+APATCH_PATCH; Log.i("aaa","App:"+patchFileString); File apatchPatch = new File(patchFileString); if (apatchPatch.exists()){ Log.i(TAG, "补丁文件存在"); try { mPatchManager.addPatch(patchFileString); } catch (IOException e) { Log.i(TAG, "打补丁出错了"); e.printStackTrace(); } }else { Log.i(TAG, "补丁文件不存在"); } }}这里只是模拟,其实真正的是会通过固定的网络通道下载.apatch文件,然后进行更新
2 下面是模拟修复前和修复后的代码
修复前:
public class MainActivity extends AppCompatActivity { public Button mBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtn = (Button) findViewById(btn); String patchFileString = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+APATCH_PATCH; Log.i("aaa",""+"MainActivity"+patchFileString); mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "出现bug了", Toast.LENGTH_SHORT).show(); } }); }}修复后:
public class MainActivity extends AppCompatActivity { public Button mBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtn = (Button) findViewById(btn); String patchFileString = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+APATCH_PATCH; Log.i("aaa",""+"MainActivity"+patchFileString); mBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "修复bug了", Toast.LENGTH_SHORT).show(); } }); }}
分别打包成apk文件:bug.apk和nobug.apk(注意要对apk文件签名)
3 然后需要使用到一个生成补丁的工具apkapatch
文件目录如下
需要将签名文件放到当前文件中,使用命令
apkpatch.bat -f nobug.apk -t bug.apk -o jiang -k mzbanner.jks -p 123456 -a w -e 123456
其中参数的意义是
-f代表修复好的apk -t代表有问题的apk -k代表签名文件 -p代表签名文件的密码 -a代表别名 -e代表别名密码
使用cmd命令打开后运行就会生成一个jiang的文件夹 里面就会有一个.apatch文件生成
我们利用反编译可以看看里面的内容
可以看到类名用_CF结尾,方法名用@MethodReplace注释,通过这种方式就可以找到需要替换的类和方法
4 最后看看结果吧
运行bug.apk的界面
当把jiang.apatch文件放入指定的SD目录后,重新打开app就会发现神奇一幕
以上就是热修复的简单案例,欢迎指正
- Android热修复原理和例子
- Android 热修复原理和实现
- Android 热修复原理
- Android热修复原理
- Android 热修复原理
- Android 热修复原理
- Android热修复原理
- Android热修复原理
- android热修复原理总结
- Android热修复原理普及
- Android热修复技术原理
- Android热修复底层原理
- android原生热修复流程和原理分析实现
- Android热修复原理(HotFix)初涉
- Android热修复实现原理以及方法
- 《探索Android热修复技术原理》总结
- Android主要热修复原理分析
- Android anfix热修复 原理剖析
- 【bzoj1030】[JSOI2007]文本生成器
- PostgreSql 使用postgis 存储地理空间信息操作以及jsonb操作示例
- [图像处理] 实验笔记
- Scala学习—类型参数
- Oracle Client11g下载安装以及本地服务名配置ORA针对PL/SQL设置小结
- Android热修复原理和例子
- iOS开发 数据存储之write
- SQL注入教程——(三)简单的注入尝试
- Selenium下拉滚动条
- nutch2.3 hadoop2.6.0 hbase0.98.8 分布式爬虫NoClassDefFoundError HBaseConfigurati
- UVA
- springMVC以post提交数据中文乱码
- hbase中出现的java.net.BindException-Problem binding to 111.175.221.58 60020
- golang二维切片赋值