方法热替换框架 – Surgeon

Surgeon

Surgeon是Android上一个简单,灵活,高性能的方法热替换框架。

集成

//添加插件 buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.2'//version参照上表 }
} //引用插件 apply plugin: 'com.android.library' apply plugin: 'com.tangxiaolv.surgeon' 或
apply plugin: 'com.android.application' apply plugin: 'com.tangxiaolv.surgeon' //添加注解解析器 dependencies {
    annotationProcessor 'com.tangxiaolv.surgeon:surgeon-compile:1.0.1'//version参照上表 }

快速入门

一:在library/application中目标方法上加上注解

package com.tangxiaolv.sdk; public class SDKActivity extends AppCompatActivity { //namespace 命名空间,通常为packageName + className,也可以自定义 //function 方法名称,通常为当前的方法名字,也可自定义 //namespace + function必须唯一,否则无法正确被替换 @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private String getTwo() { return "TWO";
    }
}

二:在替换方法上配置目标方法路径的注解

//创建新类实现ISurgeon public class HotReplace implements ISurgeon { //当前类是否为单例 @Override public boolean singleton() { return false;
    } @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public String getTwo(TargetHandle handle) { return "getTwo from HotReplace2";
    }
}

进阶

目标方法

package com.tangxiaolv.sdk; public class SDKActivity extends AppCompatActivity { @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private String getTwo() { return "TWO";
    } @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") private String getTwo(String text) { return text;
    } @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree") private String getThree(String text) { return "getThree_"+text;
    }
}

一:静态替换

public class HotReplace implements ISurgeon { @Override public boolean singleton() { return false;
    } //调用目标方法前调用 //target 目标方法所在对象 @ReplaceBefore(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoBefore(Object target) {
    } //替换目标方法 //handle 目标方法的处理类,可通过它调用目标方法和获取目标方法所在对象 @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public String getTwo(TargetHandle handle) { return "getTwo from remote";
    } //目标重载方法替换 //handle 目标方法的处理类,可通过它调用目标方法和获取目标方法所在对象 @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") public String getTwo(TargetHandle handle,String text/**目标方法参数*/) { return "getTwo from remote";
    } //目标方法调用之后调用 //target 目标方法所在对象 @ReplaceAfter(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoAfter(Object target) {
    } //替换目标方法 @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree") public String getThree(TargetHandle handle, String text) throws Throwable { String newText = text + "_hack!"; //使用新参数调用原始方法 return (String) handle.proceed(newText);
    }
}

一:动态替换

//替换目标方法返回值 Surgeon.replace("com.tangxiaolv.sdk.SDKActivity.getTwo", "Runtime result"); //替换目标重载方法返回值 Surgeon.replace("com.tangxiaolv.sdk.SDKActivity.getTwo.text", "Runtime result"); //替换目标方法 Surgeon.replace("com.tangxiaolv.sdk.SDKActivity.getTwo", new ReplacerImpl<String>(){ //params[0] = 目标方法所在对象,其他是目标方法参数 @Override public void before(Object[] params) { super.before(params);
    } //params[0] = TargetHandle,其他是目标方法参数 @Override public String replace(Object[] params) { return super.replace(params);
    } //params[0] = 目标方法所在对象,其他是目标方法参数 @Override public void after(Object[] params) { super.after(params);
    }
});

混淆

//配置混淆
-keep class * implements com.surgeon.weaving.core.interfaces.ISurgeon{*;}
-keep class * implements com.surgeon.weaving.core.interfaces.IMaster{*;}

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:方法热替换框架 – Surgeon