记录热修复随笔,文章最后附上DEMO,这里只说如何使用,达成热修复目的
一、修复前与修复后对比图
二、 代码呈现
1、写一个有bug的类
public class Bug {
private final static String tag = "BugTag";
public String getStr() {
return "一个有bug耶!";
// return "bug已经被修复了";
}
}
2、在主类中调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.tv);
Bug bug = new Bug();
String s = bug.getStr();
textView.setText(s);
}
}
3、将修bug后进行编译class文件,然后获取转成dex修复包
public class Bug {
private final static String tag = "BugTag";
public String getStr() {
// return "一个有bug耶!";
return "bug已经被修复了";
}
}
4、获取dex包步骤
1>已经修复好的进行编译
2>编译成功后找到已修复的class,如果没有,按照第一步重新编译
3>这一步开始就比较重要了,将Bug.class复制到任意一个目录中
如图是我的存放目录:
4> 找到androidSDK中build-tools中的dx.bat,,我的在C盘中
5>打开cmd进入到30.0.2的这个目录中,输入命令行
dx --dex --no-strict --output=D:\Hot\fix.dex D:\Hotfx\Bug.class
说明: D:\Hot\fix.dex为转换后输出dex路径,D:\Hotfx\Bug.class为转换的class文件路径(图第3步)
如图,显然是出现了错误,路径不对,因为我的是E盘,路径写了D盘,所以出错。
6>正确的命令转换
看到了这一步,就代表已经成功了
已经生成我们需要的dex。
7>为了方便测试,将dex放到了assets中,使用代码来进行读取
三、更多代码可以下载demo查看
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
Log.d("BugTag2", "" + getClassLoader());//PathClassLoader
Log.d("BugTag2", "" + getClassLoader().getParent());//BootClassLoader
String fixPath = "fix.dex";
try {
String path = AssetsFileUtil.copyAssetToCache(this, fixPath);
File fixFile = new File(path);
if (Build.VERSION.SDK_INT >= 23) {
ClassLoaderHookHelper.hookV23(getClassLoader(), fixFile, getCacheDir());
} else if (Build.VERSION.SDK_INT >= 19) {
ClassLoaderHookHelper.hookV19(getClassLoader(), fixFile, getCacheDir());
} else if (Build.VERSION.SDK_INT >= 14) {
ClassLoaderHookHelper.hookV14(getClassLoader(), fixFile, getCacheDir());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
demo下载
-END