33

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:

    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

    public interface Foo { 
            int get42(); 
    } 

and f.dex contains some dx'ed implementation of that interface:

    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:

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?

7
  • 1
    You have DexFile d, then never assign or use it. AFAIK, DexClassLoader is the correct approach, though I haven't used it personally. Commented Jun 11, 2010 at 12:51
  • That's true, the DexFile is some remainder of another dirty hack I tried, I'll look into DexClassLoader now. Commented Jun 11, 2010 at 13:24
  • I tried using DexClassLoader, but that doesn't work either. I created a derived class and called the superconstructor with super("/sdcard/f.jar", "/sdcard", null, getSystemClassLoader()); But no success. Wether defineClass nor findClass return any class that is attached dynamically. My suspect is that android does not support this at all, otherwise normal defineClass should work already. Probably because of some security issues. But I'd definately like to hear reasons, I also started a thread on android-developers Google group. Commented Jun 11, 2010 at 13:56
  • DexClassLoader works, as illustrated by dalvik/tests/068-classloader in the source tree. It's used by apps that want a "plugin" architecture. Bear in mind that the class is only visible by going through the custom class loader. Commented Jun 11, 2010 at 23:36
  • Maybe PathClassLoader is better: stackoverflow.com/questions/2903260/… Commented Mar 21, 2012 at 9:53

1 Answer 1

53

There's an example of 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:

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Replace "/tmp" with something else on the device.
dx.bat --dex --output=E:\classes.dex E:\test_app.jar
That's a lot better than the build.xml tweaks in android-developers.blogspot.com/2011/07/… - but is there a way to have Eclipse do the dx step on every build?
I have a question: How do you unload what you've loaded?
@Snicolas Interesting. Sadly I can't do it right now, as I have an army-draft (I'm from Israel), so I hope to remember to get back to this some time in the future. thank you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.