频道栏目
首页 > 程序开发 > 综合编程 > 其他综合 > 正文
Alibaba-Dexposed框架在线热补丁修复的使用
2015-11-18 16:10:00         来源:乔晓松  
收藏   我要投稿

这里写图片描述

前两篇已经介绍了alibaba的AndFix热修复:
Alibaba-AndFix Bug热修复框架的使用
Alibaba-AndFix Bug热修复框架原理及源码解析<喎"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPkRleFBvc2VkysdBbGliYWJhtcTB7dK7uPa/8rzco6y2vL/J0tTU2s/fyMjQ3ri0YnVno6zWu7K7uf1EZXhQb3NlZNKyv8nS1Mq1z9bG5Mv7tcS5psTcoaM8L3A+DQo8cD5EZXhQb3NlZCC96cncINOm08Ozob6wINTaQW5kcm9pZMnPtcTKudPDINTa19S2qNLlQXBwbGljYXRpb26z9cq8u68gcGF0Y2jOxLz+tcTJ+rPJINans9a1xM+1zbM8L3A+DQo8aDEgaWQ9"dexposed">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'
 }

在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);
}

当收到服务器推送消息,需要下载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());
            }

//注: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')
}

如果想修复一个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);
                    }
                });
         }
}

下面的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;
            }
        });
    }
}

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

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

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

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

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

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

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版,所以最好不要在正式的线上产品中使用它。

 

点击复制链接 与好友分享!回本站首页
相关TAG标签 框架 补丁
上一篇:调整数组使奇数全部都位于偶数前面。
下一篇:解决在Safari、IE高版本中采用自定义选择文件按钮ajaxFileUpload不能上传问题
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站