我正在为Android开发命令行工具(想想am),试图利用ByteBuddy的强大功能来支管静态方法。getApplicationContext 在android.security.KeyStore中定义
但是--ByteBuddy似乎看不到这个方法。getDeclaredMethods 的时候,因此无法拦截它。
当使用 getMethods 在反射API中,我能够列出方法。
Class AndroidKeyStore = Class.forName("android.security.KeyStore");
Method[] keyStoreMethods = new ByteBuddy()
.with(TypeValidation.DISABLED)
.subclass(AndroidKeyStore, ConstructorStrategy.Default.IMITATE_SUPER_CLASS)
.name("KeyStoreMasker")
.method(ElementMatchers.named("getApplicationContext"))
.intercept(SuperMethodCall.INSTANCE)
.make()
.load(getClass().getClassLoader(),
new AndroidClassLoadingStrategy
.Injecting(new File("/data/app/cmdutil")))
.getLoaded()
.getDeclaredMethods();
for(i = 0; i < keyStoreMethods .length; i++) {
System.out.println("method = " + keyStoreMethods[i].toString());
}
当运行上面的内容时,我期望有一个单一的方法- getApplicationContext 的子类中。然而这个子类并不包含任何方法。
取代对 getDeclaredMethods 由 getMethods 我能够列出超类的所有公共方法。
通过将被拦截的方法替换为一个非静态方法(例如 "state"),我可以使用ByteBuddy的 getDeclaredMethods 函数。
在keyStoreMethods中声明的方法数量:2。
method = public android.security.KeyStore$State AndroidKeyStoreMasker.state()
method = public android.security.KeyStore$State AndroidKeyStoreMasker.state(int)
所以我最后的结论是,ByteBuddy(或者说我使用ByteBuddy的使用案例)的静态方法可见性存在一些问题。
参考android.security.KeyStore.java。https:/android.googlesource.complatformframeworksbase+masterkeystorejavaandroidsecurityKeyStore.java。
任何帮助都将是非常感激的。
当创建一个 subclass
,Byte Buddy只能截取子类直接声明的方法或超级类的虚拟方法。这就是JVM的工作原理。static
方法是直接在接收器上调度的。
Byte Buddy也能够重新定义和重构现有的类,但这需要一个Java代理,而Android上是没有的。因此,恐怕你需要找到一个非静态钩子点来完成你的尝试。另外,你也可以看看 MemberSubstitution
在那里你可以从你的代码中重定向此类调用。这也需要重新转换,但由于它发生在你的代码中,你可以使用Byte Buddy的构建插件。