博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
介绍自己的一个Android插桩热修复框架项目QuickPatch
阅读量:6199 次
发布时间:2019-06-21

本文共 1778 字,大约阅读时间需要 5 分钟。

QuickPatch项目地址:

和 同步更新

类似于美团的Robust插桩热修复,但是代码可读性比较强,还在继续完善,todo list在项目README里

QuickPatch项目介绍

年轻人的第一个Android插桩热修复框架

基于函数插桩,兼容性好(Android版本升级不需要做修改),支持热更新无需重启app,参考了美团的Robust插桩热修复框架,精简了很多实现细节,代码可读性高

一句话原理

简单地讲,就是通过编译时在每个函数的头部插入一个if判断和一个proxy代理,就可以在运行时动态替换实现,无需重启。代码如下:

protected void onCreate(Bundle savedInstanceState) {    if (_QPatchStub != null) {        // _QPatchStub.proxy() will check method existance and call it        MethodProxyResult proxyResult = _QPatchStub.proxy(this, "onCreate", "(Landroid/os/Bundle;)V", new Object[]{savedInstanceState});        if (proxyResult.isPatched) {            return;        }    }    // origin implementation below    super.onCreate(savedInstanceState);    // ...}

设计思路

  • QuickPatch和美团Robust的区别是,Robust的编译和dex阶段分别使用ASM和Smali做了处理,QuickPatch仅在gradle编译java到class阶段使用Javassist处理,逻辑简单
  • 不支持自动生成dex补丁(复杂度高,代码可读性差),所以需要手动生成补丁,但是提供了补丁类模版,写起来很方便
  • 对于super的处理使用native调用CallNonVirtual##TYPE##Method()系列方法实现
  • 计划支持构造函数和增加成员函数的热修复
  • 可能计划支持非Android的纯Java代码的热修复

DEMO

demo

使用说明

  • 打开app/build.gradle中的一行apply plugin: 'quickpatch.gradleplugin'
  • 然后使用AndroidStudio或者./gradlew执行下面任务:
./gradlew gradleplugin:uploadArchives # 编译插桩插件./gradlew app:installDebug # 使用插件编译app代码并插桩
  • 为了方便点击app内的Enable Patch按钮可以模拟补丁加载效果,实际上是使用原本的ClassLoader加载了apk内打包好的的QPatch类
  • 同包名下后缀是_QPatch的类是补丁类,如MainActivity类的补丁类对应名字是MainActivity_QPatch
  • 接下来框架代码会使用一个新的ClassLoader加载dex,然后反射识别并查找相应的函数是否存在,如果存在则新的函数里面的逻辑会被调用
  • 补丁文件名一般是patch.dex, 生成dex需要手动使用命令,比如dx --dex --output=patch.dex MainActivity_QPatch.class
  • 补丁文件需要手动放置到sd卡下,比如adb push patch.dex /sdcard/
  • 然后点击app内的Enable Patch按钮即可实时加载补丁,看到pid不会有变化

性能优化思路

  1. 减少没有patch的时候所有函数调用损耗
  2. 减少有patch时,但没有走到patch涉及到的类时的损耗
  3. 减少有patch时,走到patch类,但是没走到patch函数时的损耗
  4. 减少有patch时,走到patch类,并走到patch函数时的损耗
  5. 优化patch函数内不包含反射,和包含native反射或java反射的这三种情况

转载于:https://blog.51cto.com/13941246/2164761

你可能感兴趣的文章
Java 对称数据加密AES
查看>>
MongoDB分布式集群搭建(分片加副本集)
查看>>
lambda 表达式树
查看>>
day5 笔记
查看>>
安装最新Nginx
查看>>
周末大放送网站图片上传,水印,预览,截图
查看>>
【BZOJ 2654】tree
查看>>
Webpack 2 设置为从当前文件夹逐级向上查找模块
查看>>
【转载】MySQL常用系统表大全
查看>>
Stay Hungry, Stay Foolish--2005斯坦福大学05年毕业演讲
查看>>
浙江电信张涛:天翼阅读未来将收费 资费采用包月形
查看>>
[转载] 百科全说——漆浩:观手分辨五行人教您五行人的养生绝招(11-01-10&11-01-11)...
查看>>
How to use the Custom Material node and create Metaballs 官方视频学习笔记
查看>>
各种HTTP状态的含义
查看>>
51nod 1238 最小公倍数之和 V3
查看>>
CSS与JQuery的相关问题
查看>>
hashmap hashtable 的区别
查看>>
文件方式实现完整的英文词频统计实例
查看>>
修改屏幕亮度
查看>>
day 10 7
查看>>