Как загрузить класс из массива байтов в android?

Во-первых, я видел загрузку Java-байт-кода в Runtime, и это было полезно, поскольку я попал ко мне в то же место, в котором я застрял в настоящее время.

Я пытаюсь загрузить класс из массива байтов, чтобы избежать хранения файла на диске. Для целей тестирования в этом примере я просто читаю файл .class в массив байтов, поэтому, очевидно, файл все еще хранится на диске, но просто посмотреть, может ли код работать.

Я беру этот массив байтов, а затем использую собственный ClassLoader с методом loadClass для загрузки класса, но он не работает.

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

Вот реализация 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; } 

И ошибка, которую я получаю, такова:

Java.lang.UnsupportedOperationException: невозможно загрузить этот тип файла класса в java.lang.VMClassLoader.defineClass (собственный метод)

Я поставил его с .class файлы, .dex файлы, .apk, .jar и т. Д. Я понятия не имею, что «тип файла класса» он хочет от меня, а документация на нем отсутствует. Любая помощь была бы замечательной. Я пытался получить эту работу в течение четырех дней подряд.

Убедитесь, что ваш .dex файл является подлинным исполняемым файлом Dalvik dx, а не скрытым файлом Java .class . Если вы используете расширение .dex файл должен быть .dex файлом; В противном случае используйте расширение .jar для ZIP-файла, содержащего запись classes.dex .

Не все версии Dalvik могут загружать классы из памяти. Вы можете обойти это, загрузив класс из файловой системы. В методе generateAndLoad DexMaker есть пример:

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

У меня та же проблема, что и у вас.

Причина, по которой я получаю сообщение об ошибке «не может загрузить этот тип файла класса», проста.

В источнике платформы «/dalvik/vm/native/java_lang_VMClassLoader.cpp», который связан с методом «defineClass», всегда возвращает исключение следующим образом. (Версия: ICS)

Наконец, я пришел к выводу, что я не могу загрузить .dex в формат массива байтов.

Есть ли кто-нибудь, кто может загрузить .dex с помощью байтового массива? (Не используя файлы)

 /* * static Class defineClass(ClassLoader cl, String name, * byte[] data, int offset, int len) * throws ClassFormatError * * Convert an array of bytes to a Class object. */ static void Dalvik_java_lang_VMClassLoader_defineClass(const u4* args, JValue* pResult) { Object* loader = (Object*) args[0]; StringObject* nameObj = (StringObject*) args[1]; const u1* data = (const u1*) args[2]; int offset = args[3]; int len = args[4]; char* name = NULL; name = dvmCreateCstrFromString(nameObj); ALOGE("ERROR: defineClass(%p, %s, %p, %d, %d)", loader, name, data, offset, len); dvmThrowUnsupportedOperationException( "can't load this type of class file"); free(name); RETURN_VOID(); } /* * static Class defineClass(ClassLoader cl, byte[] data, int offset, * int len) * throws ClassFormatError * * Convert an array of bytes to a Class object. Deprecated version of * previous method, lacks name parameter. */ static void Dalvik_java_lang_VMClassLoader_defineClass2(const u4* args, JValue* pResult) { Object* loader = (Object*) args[0]; const u1* data = (const u1*) args[1]; int offset = args[2]; int len = args[3]; ALOGE("ERROR: defineClass(%p, %p, %d, %d)", loader, data, offset, len); dvmThrowUnsupportedOperationException( "can't load this type of class file"); RETURN_VOID(); } 

Android не запускает байт-код JVM, но байт-код Dalvik. Таким образом, ваша операция должна включать эту строку перед defineClass()

 context.setOptimizationLevel(-1); 
Intereting Posts
После извлечения кода в виджет lib больше не работает Пробелы между элементами GridView Android – стандартный способ спросить пользователя о тарифном приложении и дать возможность поделиться ссылкой с друзьями Android – методы в DialogListener, прикрепленные к Facebook.authorize () не попадают Предупреждение о сбое данных для Android Предупреждение: ссылки на методы, использующие '.' не рекомендуется Android: потребление игровой памяти LibGDX 2D LinearLayout: layout_gravity = "bottom" не работает на горизонтальном LinearLayout Показать мягкую клавиатуру для диалога Пользовательский TableLayout с несколькими TextViews в строках Использовать Parcelable с объектом с помощью Hashmap AppBarLayout с recyclerView во вложенном фрагменте Проверьте целевой уровень API проекта сборки Android во время выполнения Дооснащение + OkHttp + GZIP-ed JSON Как обнаружить, что навигационный ящик был открыт с помощью прокрутки (а не домашнего значка)? Android Custom PopupWindow / Dialog