如何在 android/dalvik 上动态加载 Java 类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3022454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to load a Java class dynamically on android/dalvik?
提问by anselm
I'm wondering if and how one can load dex or class files dynamically in dalvik, some quick'n'dirty test function I wrote was this:
我想知道是否以及如何在 dalvik 中动态加载 dex 或类文件,我编写的一些快速的测试函数是这样的:
public void testLoader() {
InputStream in;
int len;
byte[] data = new byte[2048];
try {
in = context.getAssets().open("f.dex");
len = in.read(data);
in.close();
DexFile d;
Class c = defineClass("net.webvm.FooImpl", data, 0, len);
Foo foo = (Foo)c.newInstance();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
whereas the Foo interface is this
而 Foo 接口是这个
public interface Foo {
int get42();
}
and f.dex contains some dx'ed implementation of that interface:
和 f.dex 包含该接口的一些 dx'ed 实现:
public class FooImpl implements Foo {
public int get42() {
return 42;
}
}
The above test driver throws at defineClass() and it doesn't work and I investigated the dalvik code and found this:
上面的测试驱动程序抛出了defineClass()并且它不起作用,我调查了dalvik代码并发现了这个:
http://www.google.com/codesearch/p?hl=en#atE6BTe41-M/vm/Jni.c&q=Jni.c...
http://www.google.com/codesearch/p?hl=en#atE6BTe41-M/vm/Jni.c&q=Jni.c...
So I'm wondering if anyone can enlighten me if this is possible in some other way or not supposed to be possible. If it is not possible, can anyone provide reasons why this is not possible?
所以我想知道是否有人可以启发我这是否可能以其他方式或不应该是可能的。如果不可能,谁能提供为什么这是不可能的原因?
采纳答案by Jesse Wilson
There's an exampleof DexClassLoader in the Dalvik test suite. It accesses the classloader reflectively, but if you're building against the Android SDK you can just do this:
Dalvik 测试套件中有一个DexClassLoader示例。它反射性地访问类加载器,但如果您是针对 Android SDK 构建的,则可以这样做:
String jarFile = "path/to/jarfile.jar";
DexClassLoader classLoader = new DexClassLoader(
jarFile, "/tmp", null, getClass().getClassLoader());
Class<?> myClass = classLoader.loadClass("MyClass");
For this to work, the jar file should contain an entry named classes.dex
. You can create such a jar with the dx
tool that ships with your SDK.
为此,jar 文件应包含一个名为classes.dex
. 您可以dx
使用 SDK 附带的工具创建这样的 jar 。