2010-06-11 17 views
30

Tôi tự hỏi nếu và làm thế nào người ta có thể tải các tập tin dex hoặc lớp động trong Dalvik, một số chức năng kiểm tra quick'n'dirty tôi đã viết là thế này:Làm thế nào để tải một lớp Java động trên 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(); 
      } 
    } 

trong khi giao diện Foo là này

public interface Foo { 
      int get42(); 
    } 

và f.dex chứa một số thực hiện của giao diện dx'ed rằng:

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

Người lái xe thử nghiệm trên ném tại defineCl ass() và nó không công việc và tôi điều tra mã Dalvik và thấy điều này:

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

Vì vậy, tôi tự hỏi nếu có ai có thể soi sáng cho tôi nếu điều này là có thể trong một số khác cách hay không được cho là có thể. Nếu không thể, ai cũng có thể đưa ra lý do tại sao điều này là không thể?

+1

Bạn có 'DexFile d', sau đó không bao giờ gán hoặc sử dụng nó. AFAIK, 'DexClassLoader' là cách tiếp cận chính xác, mặc dù tôi đã không sử dụng nó một cách cá nhân. – CommonsWare

+0

Đó là sự thật, DexFile là phần còn lại của một hack bẩn tôi đã thử, tôi sẽ xem xét DexClassLoader bây giờ. – anselm

+0

Tôi đã thử sử dụng DexClassLoader, nhưng điều đó không hoạt động. Tôi đã tạo một lớp dẫn xuất và được gọi là superconstructor với siêu ("/ sdcard/f.jar", "/ sdcard", null, getSystemClassLoader()); Nhưng không thành công. Wether defineClass cũng không findClass trả về bất kỳ lớp nào được gắn động. Nghi ngờ của tôi là Android không hỗ trợ điều này, nếu không thì defineClass bình thường sẽ hoạt động. Có lẽ vì một số vấn đề bảo mật. Nhưng tôi chắc chắn muốn nghe lý do, tôi cũng bắt đầu một chủ đề trên nhóm phát triển Android của Google. – anselm

Trả lời

47

Có một example của DexClassLoader trong bộ thử nghiệm Dalvik. Nó truy cập vào classloader phản tư, nhưng nếu bạn đang xây dựng so với Android SDK bạn chỉ có thể làm điều này:

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

Để làm việc này, các file jar nên chứa một mục tên là classes.dex. Bạn có thể tạo một cái lọ bằng công cụ dx đi kèm với SDK của bạn.

+2

Thay thế "/ tmp" bằng một thứ khác trên thiết bị. – fadden

+0

Cảm ơn tôi có thể xác nhận điều này hoạt động ngay bây giờ, tuyệt vời! – anselm

+2

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

Các vấn đề liên quan