dexposed框架总结

本文介绍了阿里巴巴的Dexposed框架,一个非侵入式的Android运行时AOP框架,基于Xposed实现。内容包括Dexposed的功能特性、经典应用场景、集成步骤以及基本使用方法,如方法拦截和热补丁技术。同时,分享了作者在集成过程中的实践经验,包括解决遇到的问题和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章主要写一下我使用 dexposed 的一个简单流程。

一开始就不多废话了,总之dexposed是阿里巴巴新开源的一个非侵入式的AOP框架。

GitHub传送门:https://github.com/alibaba/dexposed

以下翻译自 GitHub:

1Dexposed是什么:

Dexposed Android 应用开发一个功能强大且非侵入式的运行时 AOP(面向方向编程)框架,他是基于开源的 Xposed 框架实现的。

Dexposed AOP 实现是完全非侵入式的,没有使用任何注解处理器,编织器或字节码重写。集成 Dexposed 框架很简单,只需要使用一行代码,在程序的初始化阶段加载一个小小的 JNI 库即可。

Dexposed 不仅可以 hook 你自己的程序代码,也可以 hook 你的应用程序中调用的 Android 框架中的函数。开发者经常严重的依赖 Fragment 碎片化来开发程序,这个功能对这一情况大有用处。

机遇动态加载的机制,运行中的 app 可以加载一小段经过编译的 Java AOP 代码,在不需要重新启动程序的情况下改变目标 app 的行为。

2、经典实用场景

1、经典 AOP 编程

2、仪表化 (Instrumentation) ,用于测试,性能监控等

3、在线热修复,用于修复,紧急漏洞,安全漏洞、

4SDK hook ,以提供更好的开发体验。

3、集成

这部分是我个人集成详细过程,和官方给的方法可能有出入。(因为我按它说的做根本没弄好(⊙﹏⊙)b

首先先把 GitHub 上的东西下载下来解压后打开,目录如下:


Android Studio 上新建项目 DexposedDemo。把 dexposed\src\main 目录下的 jniLibs 文件夹拷贝到自己项目的 src/main 目录下。在自己的项目中添加一个包,取名为 com.taobao.android.dexposed ,接着把 dexposed\src\main\java\com\taobao\android\dexposed  下的源码都复制到 com.taobao.android.dexposed 包中。。添加后,在 Project 视图中,目录结构如下:


接下来检测设备是否支持 dexposed 框架,根据官方文档,因在程序中今早进行检测,所以这段代码被放到 MyApplication 类中。

package com.bajie.dexposed;
import android.app.Application;
import android.os.Build;
import android.util.Log;
import com.taobao.android.dexposed.DexposedBridge;
public class MyApplication extends Application {
    private static final String TAG = "MyApplication";
    private boolean mCanDexposed = false;
    @Override
    public void onCreate() {
        super.onCreate();
        mCanDexposed = DexposedBridge.canDexposed(this);
        Log.i(TAG, "canDexposed = " + mCanDexposed);
    }
    public boolean canDexposed() {
        return mCanDexposed;
    }
}

别忘了在 manifest 文件中配置 application 哦:

<application
        android:name=".MyApplication" />

4.基本使用方法

针对一个方法,可以用三种方法对它进行改造,分别是:方法前,方法后,替代方法。

比如有一个显示 Toast 的方法如下:

private void showToast() {
    toast = Toast.makeText(this, "this is a toast", Toast.LENGTH_SHORT);
}

我们想在这个方法执行前或执行后在一个 TextView 中显示消息,可以这样实现:

private void hookShowToast() {
    DexposedBridge.findAndHookMethod(this.getClass(), "showToast", new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            super.beforeHookedMethod(param);
        }

        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            super.afterHookedMethod(param);
            tv.setText("showToast() afterHooked");

        }
    });
}

Dexposed 框架还可以替换掉整个函数:

private void methodReplacement() {
    if(canDexposed) {
        DexposedBridge.findAndHookMethod(this.getClass(), "showToast", new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                Toast.makeText(MainActivity.this, "this is a replacement toast", Toast.LENGTH_SHORT).show();
                return null;
            }
        });
    }
}

Dexposed 还拥有热补丁的方法。就是在项目上线的时候,在不发布新版本的情况下,动态修复线上的 bug 的功能。

首先先建一个 Patch 项目作为补丁,引入 dexposedbridge.jar patchloader.jar,在目标项目中加入 com.taobao.android.dexposed.patch 下面的源码,这里需要注意,需要在目标项目中加入读 SdCard 的权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

首先在 目标项目中添加此方法

public void runPathApk() {
    String fullPath = Environment.getExternalStorageDirectory() + File.separator + "patch.apk";
    setText("\n" + fullPath);
    PatchResult result = PatchMain.load(this, fullPath, null);
    if (result.isSuccess()) {
        setText("patch success!");
    } else {
        setText("\n" + result.getErrorInfo());
    }
}

其中 fullPath 为补丁 apk 的路径,可以自定义,当然在路径中你需要放入补丁 apk

接着在补丁中添加类:

public class ToastPach implements IPatch {

    @Override
    public void handlePatch(PatchParam patchParam) throws Throwable {
        final Class<?> cls = patchParam.context.getClassLoader().loadClass("com.bajie.dexposed.MainActivity");
        DexposedBridge.findAndHookMethod(cls, "showToast", new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                Toast.makeText((Activity)param.thisObject, "success", Toast.LENGTH_LONG).show();
                return null;
            }
        });
    }
}

补丁项目中只需要实现此类就可以,然后把补丁项目打包,放到相应的位置,运行原来的项目,在这里,showToast 方法将被替换掉。

需要注意几点是,我当时用gradle2.0.2-beta6 进行运行的时候,没办法使用,后来改成 gradle:1.5.0 就可以运行了。























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值