2010-06-11 12 views
30

Zastanawiam się, czy i jak można załadować Dex lub klasa plików dynamicznie w Dalvik, niektóre funkcja testu quick'n'dirty pisałem było to:Jak załadować klasę Java dynamicznie na Android/Dalvik?

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

natomiast interfejs Foo jest to

public interface Foo { 
      int get42(); 
    } 

i f.dex zawiera pewne dx'ed wdrożenie tego interfejsu:

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

powyższy kierowca testowy rzuca na defineCl osioł() i nie pracę i badałem kod Dalvik i stwierdziliśmy:

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

Więc zastanawiam się, czy ktoś może mnie oświecić, czy jest to możliwe w niektórych innych sposób lub nie powinien być możliwy. Jeśli nie jest to możliwe, może podać przyczyny, dla których nie jest to możliwe?

+1

Masz 'DexFile d', a następnie nigdy go nie przypisuj ani nie używaj. AFAIK, 'DexClassLoader' to poprawne podejście, chociaż nie używałem go osobiście. – CommonsWare

+0

To prawda, DexFile jest pozostałością po innym plugawym hackzie, którego próbowałem, zajrzę teraz do DexClassLoader. – anselm

+0

Próbowałem używać DexClassLoader, ale to też nie działa. Stworzyłem klasę pochodną i nazwałem superkonstruktorem z super ("/ sdcard/f.jar", "/ sdcard", null, getSystemClassLoader()); Ale bez powodzenia. Wether defineClass ani findClass nie zwracają żadnej klasy, która jest dołączana dynamicznie. Podejrzewam, że Android nie obsługuje tego w ogóle, w przeciwnym razie normalna funkcja defineClass powinna już działać. Prawdopodobnie z powodu pewnych problemów z bezpieczeństwem. Ale zdecydowanie chciałbym usłyszeć powody, zacząłem też wątek na grupie Google dla programistów Android. – anselm

Odpowiedz

47

W pakiecie testowym Dalvik znajduje się example DexClassLoader. Jest dostęp do classloader refleksyjnie, ale jeśli budujemy przeciwko Android SDK można po prostu to zrobić:

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

Aby to działało, plik jar powinien zawierać wpis o nazwie classes.dex. Możesz utworzyć taki słoik za pomocą narzędzia dx dostarczanego z zestawem SDK.

+2

Zamień "/ tmp" na coś innego w urządzeniu. – fadden

+0

Dzięki, mogę potwierdzić, że teraz działa, świetnie! – anselm

+2

dx.bat --dex --output = E: \ classes.dex E: \ test_app.jar – diyism

Powiązane problemy