ReInjectPlugin:通过ASM实现无侵入修改工程文件

ReInjectPlugin

类似于AOP编程或Xposed,我们经常发现下面的这些场景,需要添加一些代码,但又不想在原来的项目业务逻辑:

  • 性能打点:对http, 文件访问,数据库访问,rpc调用
  • 业务打点:如界面打点工具,记录进出每一个activity的时间
  • 实例监控:记录某一个特定对象的分配和释放情况,用于调测定位内存泄漏的场景

这些要修改的文件,一方面有可能是三方库的代码,如sqlite,okhttp等,必须要编译自己的版本或在本项目内做一个封装类,才能拦截到;
也有可能,这些类的修改涉及非常多,修改非常发散。
ReInjectPlugin正是为了解决此类问题而来,只需要写好配置文件,并编写拦截后的代码,就可以实现对apk内任何一个类的注入和修改。

使用说明

添加插件配置

插件已发布到mavenCenter,需要添加mavenCenter作为开源引用仓。
修改根项目build.gradle文件,添加脚本引用说明

buildscript {
    dependencies {
        classpath 'io.github.nylon009:reinject-plugin:0.0.1'
    }
}

在app/build.gradle使用此插件

plugins {
    id 'io.github.nylon009.reinject-plugin'
}

配置文件

在app工程下增加ReInject.json配置文件
注意在实现类InjectUtils中,静态方法和动态方法的拦截实现类是不一样的。
动态方法拦截时,第一个参数永远是原来调用的类实例,这样可以方便获取实例内部的信息,甚至修改成员值。

{
  "injects": [
    {
      "className": "com.nylon.app.Utils",
      "methodName": "foobar",
      "methodSignature": "(Ljava/lang/String;)V",
      "injectClassName": "com.nylon.app.InjectUtils",
      "injectEnterMethodName": "foobarEnter",
      "injectExitMethodName": "foobarExit"
    },
    {
      "className": "com.nylon.app.Utils",
      "methodName": "hello",
      "methodSignature": "(Ljava/lang/String;)V",
      "injectClassName": "com.nylon.app.InjectUtils",
      "injectEnterMethodName": "helloEnter",
      "injectExitMethodName": "helloExit"
    }
  ]
}

拦截静态方法

原始代码com.nylon.app.Utils

public static void foobar(String test){
    Log.d(TAG, "foobar");
}

编译完成后,通过jadx可以查看修改后的代码如下:

public static void foobar(String test) {
    InjectUtils.foobarEnter(test); // 这一行是注入的代码
    Log.d(TAG, "foobar");
    InjectUtils.foobarExit(test);  // 这一行是注入的代码
}

注入非静态函数

原始类com.nylon.app.Utils

public void hello(String msg) {
    Log.d(TAG, "hello " + msg);
}

注入后的代码

public void hello(String msg) {
    InjectUtils.helloEnter(this, msg); // 这一行是注入的代码,第一个参数是新增参数
    Log.d(TAG, "hello " + msg);
    InjectUtils.helloExit(this, msg); // 这一行是注入的代码,第一个参数是新增参数
}

怎么样修改插件并调试

修改Plugin模块中,发布插件的版本号,并通过以下命令发布到本地repo目录

 ./gradlew :Plugin:assemble :Plugin:publishAllPublicationsToMyRepoRepository

在项目里已添加了repo目录为maven仓,因此无须再手动添加。
更新app/build.gradle里插件使用的版本号,就可以用上新版本了。

其它

项目地址: github ReInjectPlugin
项目在实现时,参考了AndroidPluginStudy的部分实现代码,在此表示感谢。

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值