问题
I am developing an Android app with a 3rd-party library. I want to replace a method call in the library. Please note that I cannot obtain the library's source code, so that I have to change it at runtime.
For example, let's assume there is doA()
method in a class Foo in the library
class Foo {
doA() {
//method body
}
...
}
I want to replace the method body of doA()
with my own code. I have done some exploration and found the following stackoverflow thread: Replacing a method call in a class at runtime. The thread tells me that I may try a bytecode manipulation library called javassist. I found there is an Android-version of that library at here: https://github.com/crimsonwoods/javassist-android. I imported the library and wrote following code:
try {
final ClassPool cp = ClassPool.getDefault(getApplicationContext());
CtClass cc = cp.get("Foo");
CtMethod method = cc.getMethod("doA","()V");
method.setBody("{ java.lang.System#out.println(\"doA() is called.\");}");
cc.writeFile(); //where the exception was raised
} catch (Exception e) {
e.printStackTrace();
}
But I encountered an exception when executing cc.writeFile()
. It is "FileNotFoundException: ./Foo.class: open failed: ENOENT (No such file or directory)"
. I do not know how to address this problem.
回答1:
Your code is probably trying to save new class file which is not possible. There are huge differences between Java and Android as Android is not using normal .class files but .dex file instead.
You should follow this sample: https://github.com/crimsonwoods/javassist-android/blob/master/javassistSample/src/org/jamruby/javassistsample/MainActivity.java
来源:https://stackoverflow.com/questions/24437105/android-replace-a-method-call-at-runtime