0%

(译)Xposed Helpers

原文地址。主要讲解Xposed框架helper类里的各种方法。

Xposed中有许多Helper方法使得模块的开发变得更为简单。

# XposedBridge类

log

log方法是一个向标准logcat和/data/xposed/debug.log文件输出错误信息的简单方式。它可以捕获日志信息或者一个Throwable对象。后面的例子中,它将打印堆栈踪迹。

hookAllMethods / hookAllConstructors

如果你想把所有的方法都以一个指定的名称hook起来,或是hook类中所有的构造函数,你可以使用这两种方法。当有许多不同的变量,可是你希望在它们当中任何一个被调用之前/后都执行一段代码时,这是非常有用的。时刻记住,其它的ROM也许有额外的变量同样也被hook。尤其小心你在回调时得到的args

# XposedHelpers类

我建议把这个类添加到Eclipse的静态导入的偏好设置中:Window => Preferences => Java => Editor => Content Assist => Favorites => New Type,输入:de.robv.android.xposed.XposedHelpers。这样做的话,eclipse在你开始输入“get…”时会自动提示这个类中的方法,并且会创建这个方法的静态导入(这意味着在你的代码中是看不到类名的)。

findMethod / findConstructor / findField

有许多你不必亲自使用反射获得方法、构造函数和字段的方式。同样,你也可以对几个特定参数种类使用“最佳匹配”来寻找方法和构造函数。比如:你可以用一个TextView类型的参数来调用findMethodBestMatch(Class<?> clazz, String methodName, Object... args)。如果没有更加符合匹配的变量,这同样会找到一个具有你指定的名称而且以View类型对象作为参数的方法。

callMethod / callStaticMethod / newInstance

利用上文提到的findXXX方法,这些方法使得调用方法和创建一个类的实例变得简单。调用者不必为此而使用反射。没有必要事先就取得某个方法,只要及时使用以上的这些方法调用它就可以了。参数类型是从实际的参数值和最匹配的被调用方法中自动拷贝而来。万一你想明确的指出参数的类型,创建一个Class<?>数组,然后把它传递给callXXX/newInstance。你可以使数组中的一些项为空(null)来使用实际参数的类型。但是数组的长度必须和参数的个数匹配。

getXXXField / setXXXField / getStaticXXXField /setStaticXXXField

它们是让你能够轻易获得和设置对象实例和类变量内容的封装器。你只需要对象的引用、字段名、和类型(当然还有提供给setter的新值)。如果你想获得/设置一个静态字段,并且没有对象的引用,你可以使用getStaticXXXsetStaticXXX方法。然而当你有一个对象的引用时,区分静态和实例字段是没有必要的。getXXXsetXXX可以给两者都设定值。

getAdditionalXXXField / setAdditionalXXXField

这些方法让你将任何值与一个对象的实例或是整个类(像是一个静态字段)联系起来。这些值依照关键字-值对的方式存储。所以每个对象可以存储多个值。关键字可以是任何字符串,包括对象实际拥有的字段的名称。请注意你不能通过调用getAdditionalInstanceField获取你之前用setAdditionalStaticField存储的值。取而代之的是应该使用getAdditionalStaticField。它有一个变量来接受对象并自动查询它的类。

assetAsByteArray

这个方法以byte数组的形式返回资源。如果你想加载你模块的资源,你可以使用以下代码:

public class XposedTweakbox implements IXposedHookZygoteInit {
    @Override
    public void initZygote(StartupParam startupParam) throws Throwable {
        Resources tweakboxRes = XModuleResources.createInstance(startupParam.modulePath, null);
        byte[] crtPatch = assetAsByteArray(tweakboxRes, "crtfix_samsung_d506192d5049a4042fb84c0265edfe42.bsdiff");
...

getMD5Sum

返回文件系统中一个文件的MD5值。当前的app需要获取读这个文件的权限(在init方法中你拥有root权限,所以这应该不是什么问题)。

getProcessPid

按照进程的/proc/[pid]/cmdline的第一部分来寻找这个进程,并以字符串形式返回它的PID。