Alibaba-Dexposed框架在线热补丁修复的使用

    xiaoxiao2021-04-18  70

    转:http://blog.csdn.net/qxs965266509/article/details/49821413

    目录(?)[-]

    DexPosed 介绍应用场景在Android上的使用 在自定义Application初始化 patch文件的生成支持的系统

    前两篇已经介绍了alibaba的AndFix热修复:  Alibaba-AndFix Bug热修复框架的使用  Alibaba-AndFix Bug热修复框架原理及源码解析

    DexPosed是Alibaba的另一个框架,都可以在线热修复bug,只不过DexPosed也可以实现其他的功能。

    DexPosed 介绍应用场景在Android上的使用 在自定义Application初始化 patch文件的生成支持的系统

    DexPosed

    介绍

    DexPosed是强大而无侵入的AOP(面向切面编程)运行Android应用程序开发框架,基于开源的Xposed框架项目的工作(Xposed是修改系统框架服务的框架)。  Github : https://github.com/alibaba/dexposed

    应用场景

    AOP编程  仪表(用于测试,性能监测等)  在线热补丁修复  SDK hooking(钩)以提供更好的开发体验

    在Android上的使用

    Android Studio中使用:  在Gradle中添加:

    dependencies { compile 'com.taobao.android:dexposed:0.1.1@aar' } 123 123

    在libs中加入:dexposedbridge.jar、patchloader.jar包。  需要添加的so文件有:libdexposed.so、libdexposed_1.so。

    在自定义Application初始化

    if (DexposedBridge.canDexposed(this)) {//判断系统是否支持DexPosed Log.e("APP", "true application"); } else { Log.e("APP", "false application"); } 12345 12345

    当收到服务器推送消息,需要下载patch文件,下载完成后即时加载来修复bug。  PatchResult result = PatchMain.load(this, “patch apk文件的路径”, null);

    //加载patch apk文件 PatchResult result = PatchMain.load(this, fullpath, null); if (result.isSuccess()) { Log.e("Hotpatch", "patch success!"); } else { Log.e("Hotpatch", "patch error is " + result.getErrorInfo()); } 1234567 1234567

    //注:patch apk 文件不能放在共享目录中,建议放在cache文件中。  在应用升级之前需每次load加载patch apk,当应用升级后把patch apk进行清空。  PatchMain.load加载patch apk,会遍历apk中实现IPatch接口的所有,并hook对应的方法对象。

    patch文件的生成

    新创建一个项目MyPatch,并在libs中加入dexposedbridge.jar、patchloader.jar包。  在build.gradle设置jar为provided,如下:

    dependencies { provided files('libs/dexposedbridge.jar') provided files('libs/patchloader.jar') } 1234 1234

    如果想修复一个bug,需在MyPatch中创建一个类,并实现IPatch接口,实现handlePatch方法。

    接下的Demo是想在bug方法的前后做一些处理,也可以终止bug方法的调用及修改bug方法的参数:

    package com.open.cool.patch; import android.util.Log; import android.view.View; import android.widget.Toast; import com.taobao.android.dexposed.DexposedBridge; import com.taobao.android.dexposed.XC_MethodHook; import com.taobao.patch.IPatch; import com.taobao.patch.PatchParam; //必须实现IPatch接口 public class MyPatch implements IPatch { @Override public void handlePatch(final PatchParam arg0) throws Throwable { Class<?> cls = null; try { //使用类加载器获取需要修复的方法所在的类Class cls = arg0.context.getClassLoader() .loadClass("com.open.cool.mydex1.MainActivity"); } catch (ClassNotFoundException e) { e.printStackTrace(); return; } //hook想要操作的方法,在方法前后做一些处理,XC_MethodHook //cls上边获取到的,这里的test1是有bug的方法名称,View.class是test1的参数类型,如果有多个参数就依次在后边添加View.class,Object.class,Object.class等。 DexposedBridge.findAndHookMethod(cls, "test1", View.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); Log.e("IPatch", "beforeHookedMethod"); //TODO 调用hook方法前的操作 Toast.makeText(arg0.context, "before", Toast.LENGTH_SHORT).show(); // param.setResult(null);//禁止调用原方法 } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); //TODO 调用hook方法后的操作 Log.e("IPatch", "afterHookedMethod"); } }); } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051

    下面的Demo是直接替换掉bug方法:

    package com.open.cool.patch; import android.util.Log; import android.view.View; import android.widget.Toast; import com.taobao.android.dexposed.DexposedBridge; import com.taobao.android.dexposed.XC_MethodHook; import com.taobao.android.dexposed.XC_MethodReplacement; import com.taobao.patch.IPatch; import com.taobao.patch.PatchParam; //必须实现IPatch接口 public class MyPatch implements IPatch { @Override public void handlePatch(final PatchParam arg0) throws Throwable { Class<?> cls = null; try { //使用类加载器获取指定的类Class cls = arg0.context.getClassLoader() .loadClass("com.open.cool.mydex1.MainActivity"); } catch (ClassNotFoundException e) { e.printStackTrace(); return; } // //替换hook方法中的方法实现,XC_MethodReplacement DexposedBridge.findAndHookMethod(cls, "test1", View.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable { //TODO 替换后的方法实现 //..... return null; } }); } } 12345678910111213141516171819202122232425262728293031323334353637383940 12345678910111213141516171819202122232425262728293031323334353637383940

    上面2个Demo两者的区别是:回调接口的类不同(XC_MethodHook和XC_MethodReplacement);  //XC_MethodHook是XC_MethodReplacement的基类。

    把MyPatch项目打包生成补丁apk文件,服务器通知客户端下载补丁文件apk,并使用

    PatchResult result = PatchMain.load(this, “patch apk文件的路径”, null); 1 1

    加载补丁apk,即时修复bug方法。

    如果项目有代码混淆:  需注意的部分

    cls = arg0.context.getClassLoader() .loadClass("packageName+className"); 12 12

    packageName+className必须是混淆后的类名和方法名称。

    在打release包时,在build/outputs/mapping/release/下面有mapping.txt,这个里面记录了混淆以前的类和混淆以后的类的一一对应关系(所以叫mapping.txt),所以每次发版以后要保留好mapping.txt文件,以便以后编写Patch。

    支持的系统

    Runtime Android Version Support Dalvik 2.2 Not Test Dalvik 2.3 Yes Dalvik 3.0 No Dalvik 4.0-4.4 Yes ART 5.0 Testing ART 5.1 No ART M No

    注意:android4.4之后的版本都用Art取代了Dalvik,所以要hook Android4.4以后的版本就必须去适配Art虚拟机的机制。目前官方表示,为了适配Art的dexposed_l只是beta版,所以最好不要在正式的线上产品中使用它。

    转载请注明原文地址: https://ju.6miu.com/read-675467.html

    最新回复(0)