web-dev-qa-db-fra.com

Comment charger dynamiquement une classe Java Java sur Android / Dalvik?

Je me demande si et comment on peut charger dynamiquement des fichiers dex ou de classe dans dalvik, une fonction de test quick'n'dirty que j'ai écrite était la suivante:

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

alors que l'interface Foo est la suivante

    public interface Foo { 
            int get42(); 
    } 

et f.dex contient une implémentation dx'ed de cette interface:

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

Le pilote de test ci-dessus lance à defineClass () et cela ne fonctionne pas et j'ai étudié le code dalvik et trouvé ceci:

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

Je me demande donc si quelqu'un peut m'éclairer si cela est possible d'une autre manière ou n'est pas censé être possible. Si ce n'est pas possible, quelqu'un peut-il expliquer pourquoi cela n'est pas possible?

32
anselm

Il y a un exemple de DexClassLoader dans la suite de tests Dalvik. Il accède au chargeur de classe de manière réfléchie, mais si vous construisez avec le Android SDK, vous pouvez simplement le faire:

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

Pour que cela fonctionne, le fichier jar doit contenir une entrée nommée classes.dex. Vous pouvez créer un tel fichier jar avec l'outil dx fourni avec votre SDK.

51
Jesse Wilson