如何从android中的字节数组加载一个类?

Hum*_*ist 5 java android dynamic classloader

首先,我在运行时看到了Load Java-Byte-Code,这对我到目前为止所处的相同位置很有帮助.

我正在尝试从字节数组加载一个类,以避免在磁盘上存储文件.出于测试目的,在这个例子中,我只是将.class文件读入一个字节数组,所以显然文件仍然存储在磁盘上,但只是看看代码是否可以工作.

我使用这个字节数组,然后使用自定义ClassLoader和方法loadClass来加载一个Class,但它不起作用.

    byte[] bytearray = null;
    try{    
    RandomAccessFile f = new RandomAccessFile("/sdcard/ClassToGet.dex", "r");
    bytearray = new byte[(int) f.length()];
    f.read(bytearray);

    MyClassLoader classloader = new MyClassLoader();
    classloader.setBuffer(bytearray); 
    classloader.loadClass("com.pack.ClassIWant");
    } 
Run Code Online (Sandbox Code Playgroud)

这是ClassLoader实现:

public class MyClassLoader extends DexClassLoader {

 private byte[] buffer;

  @Override
    public Class findClass(String className){
    byte[] b = getBuffer();
    return this.defineClass(className, b, 0, b.length);
    }

public void setBuffer(byte[] b){
    buffer = b;
}
public byte[] getBuffer(){
    return buffer;
}
Run Code Online (Sandbox Code Playgroud)

我收到的错误是这样的:

java.lang.UnsupportedOperationException:无法在java.lang.VMClassLoader.defineClass(Native Method)中加载此类类文件

我已经提供了.class文件,.dex文件,.apk,.jar等...我不知道它想要什么类型的"类文件",并且它上面的文档是不存在的.任何帮助都会很棒我一直试图让这项工作连续四天.

Jes*_*son 1

确保您的.dex文件是真正的 dx 生成的 Dalvik 可执行文件,而不是.class伪装的 Java 文件。如果您使用.dex扩展名,则该文件必须是一个.dex文件;否则,请使用.jar包含条目的 ZIP 文件的扩展名classes.dex

并非所有版本的 Dalvik 都可以从内存加载类。您可以通过从文件系统加载类来解决此问题。DexMaker的 方法中有一个例子generateAndLoad

    byte[] dex = ...

    /*
     * This implementation currently dumps the dex to the filesystem. It
     * jars the emitted .dex for the benefit of Gingerbread and earlier
     * devices, which can't load .dex files directly.
     *
     * TODO: load the dex from memory where supported.
     */
    File result = File.createTempFile("Generated", ".jar", dexCache);
    result.deleteOnExit();
    JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
    jarOut.putNextEntry(new JarEntry(DexFormat.DEX_IN_JAR_NAME));
    jarOut.write(dex);
    jarOut.closeEntry();
    jarOut.close();
    try {
        return (ClassLoader) Class.forName("dalvik.system.DexClassLoader")
                .getConstructor(String.class, String.class, String.class, ClassLoader.class)
                .newInstance(result.getPath(), dexCache.getAbsolutePath(), null, parent);
    } catch (ClassNotFoundException e) {
        throw new UnsupportedOperationException("load() requires a Dalvik VM", e);
    } catch (InvocationTargetException e) {
        throw new RuntimeException(e.getCause());
    } catch (InstantiationException e) {
        throw new AssertionError();
    } catch (NoSuchMethodException e) {
        throw new AssertionError();
    } catch (IllegalAccessException e) {
        throw new AssertionError();
    }
Run Code Online (Sandbox Code Playgroud)