android在运行时替换方法调用

时间:2014-06-26 17:52:34

标签: java android methods bytecode javassist

我正在开发一个带有第三方库的Android应用程序。我想替换库中的方法调用。请注意,我无法获取库的源代码,因此我必须在运行时更改它。

例如,我们假设库中的类Foo中有doA()方法

class Foo {
    doA() {
        //method body
    }
    ...
}

我想用自己的代码替换doA()的方法体。我做了一些探索,发现了以下stackoverflow线程:Replacing a method call in a class at runtime。线程告诉我,我可能会尝试一个名为javassist的字节码操作库。我在这里找到了该库的Android版本:https://github.com/crimsonwoods/javassist-android。我导入了库并编写了以下代码:

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();
}

但是我在执行cc.writeFile()时遇到异常。它是"FileNotFoundException: ./Foo.class: open failed: ENOENT (No such file or directory)"。我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:1)

您的代码可能正在尝试保存新的类文件,这是不可能的。 Java和Android之间存在巨大差异,因为Android不使用普通的.class文件,而是使用.dex文件。

您应该遵循以下示例:https://github.com/crimsonwoods/javassist-android/blob/master/javassistSample/src/org/jamruby/javassistsample/MainActivity.java