目录现有的热修复框架很多,尤以AndFix 和Tinker比较多今天就来探讨,如何手写一个热修复的功能什么是双亲委托机制话不多说,提出了解决方法,下面着手去实现总结现有的热修复框架很
具体的实现方式和项目引用可以参考网络上的文章,今天就不谈,也不是主要目的
对于简单的项目,不想集成其他修复框架的SDK,也不想用第三方平台,只是紧急修复一些bug 还是挺方便的
言归正传,如果一个或多个类出现bug,导致了崩溃或者数据显示异常,如果修复呢,如果熟悉JVM dalvik 类的加载机制,就会清楚的了解 ClassLoader的 双亲委托机制 就可以通过这个
突破口来了,看1(如果已经加载则直接返回原来已经加载的类) 对于同一个类,如果先加载修复的类,当后续在加载未修复的类的时候,直接返回修复的类,这样bug不就解决了吗?
Nice ,多看源码和jvm 许多问题可以从framework和底层去解决
public class InitActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//这里默认在SD卡根目录,实际开发过程中可以把dex文件放在服务器,在启动页下载后加载进来
//第二次进入的时候可以根据目录下是否已经下载过,处理,避免重新下载
//最后根据当前app版本下载不同的修复dex包 等等一系列处理
String dexFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/fix.dex";
DexFile dexFile = null;
try {
dexFile = DexFile.loadDex(dexFilePath, null, Context.MODE_PRIVATE);
} catch (ioException e) {
e.printStackTrace();
}
patchDex(dexFile);
startActivity(new Intent(this, MainActivity.class));
}
public void patchDex(DexFile dexFile) {
if (dexFile == null) return;
Enumeration<String> enumeration = dexFile.entries();
String className;
//遍历dexFile中的类
while (enumeration.hasMoreElements()) {
className = enumeration.nextElement();
//加载修复后的类,只能修复当前Activity后加载类(可以放入Application中执行)
dexFile.loadClass(className, getClassLoader());
}
}
}
方法很简单在启动页,或者Application中提前加载有bug的类
这里写的很简单,只是展示核心代码,实际开发过程中,dex包下载的网络请求,据当前app版本下载不同的修复dex,文件存在的时候可以在Application中先加载一次,启动页就不用加载,等等,一系列优化和判断处理,这里就不过多说明,具体一些处理看GitHub上的代码
###ok 代码都了解了,这个 fix.dex
文件哪里来的呢 熟悉Android apk生成的小伙伴都知道了,跳过这个步骤,不懂的小伙伴继续往下看
上面的InitActivity
中startActivity(new Intent(this, MainActivity.class));
启动了一个MainActivity
看看我的MainActivity
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//0不能做被除数,这里会报ArithmeticException异常
Toast.makeText(this, "结果" + 10 / 0, Toast.LENGTH_LONG).show();
}
}
哎呀不小心,写了一个bug 0 咋能做除数呢,app已经上线了,这里必崩啊,咋办 不要急,按照以下步骤:
MainActivity
,先把bug解决 Toast.makeText(this, "结果" + 10 / 2, Toast.LENGTH_LONG).show();
把修复类生成.class
文件(可以先run一次,之后在 build/intermediates/javac/debug/classes/com开的的文件夹,找到生成的class文件,也可以通过javac 命令行生成,也可以通过右边的gradle Task生成)
.class
文件 打包成dex (其他.class
删除,只保留修复类) 打开cmd命令行,输入下面命令D:\Android\sdk\build-tools\28.0.3\dx.bat --dex --output C:\Users\pei\Desktop\dx\fix.dex C:\Users\pei\Desktop\dx\
D:\Android\sdk
为自己sdk目录 28.0.3
为build-tools
版本,可以根据自己已经下载的版本更换 后面两个目录分别是生成.dex
文件目录,和.class
文件目录
切记 .class
文件的目录必须是包名一样的,我的目录是 C:\Users\pei\Desktop\dx\com\pei\test\MainActivity.class
,不然会报 class name does not match path
再次打开App,完美Toast 结果5,完美解决
以上就是Android 手写热修复dex实例详解的详细内容,更多关于Android 手写热修复dex的资料请关注编程网其它相关文章!
--结束END--
本文标题: Android 手写热修复dex实例详解
本文链接: https://lsjlt.com/news/198527.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0