web-dev-qa-db-ja.com

JavaクラスをAndroid / dalvikに動的にロードする方法は?

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

fooインターフェースはこれです

    public interface Foo { 
            int get42(); 
    } 

f.dexには、そのインターフェースのdx化された実装が含まれています。

    public class FooImpl implements Foo { 
            public int get42() { 
                    return 42; 
            } 
    } 

上記のテストドライバーはdefineClass()でスローし、機能しません。私はdalvikコードを調査したところ、次のことがわかりました。

http://www.google.com/codesearch/p?hl=en#atE6BTe41-M/vm/Jni.c&q=Jni.c ...

それで、これが他の方法で可能であるか、可能ではないと思われる場合、誰かが私を啓蒙できるかどうか疑問に思っています。それが不可能な場合、これが不可能な理由を誰かが提供できますか?

32
anselm

Dalvikテストスイートには、DexClassLoaderの example があります。クラスローダーに反射的にアクセスしますが、Android SDKに対してビルドしている場合は、これを行うことができます:

String jarFile = "path/to/jarfile.jar";
DexClassLoader classLoader = new DexClassLoader(
    jarFile, "/tmp", null, getClass().getClassLoader());
Class<?> myClass = classLoader.loadClass("MyClass");

これが機能するには、jarファイルにclasses.dexという名前のエントリが含まれている必要があります。 SDKに付属するdxツールを使用して、このようなjarを作成できます。

51
Jesse Wilson