Динамическая генерация байт-кода Dalvik в работающее приложение Dalvik / Android
Этот вопрос был задан(и получил ответ) много раз о динамическом генерировании и загрузке байт-кодов java во время выполнения в работающую виртуальную машину Dalvik, но есть ли способ загрузить файлы dex/байт-коды в приложение во время выполнения?
Спасибо
5 ответов:
Команда Dalvik хотела бы создать первоклассную библиотеку генерации кода во время выполнения. Мы отслеживаем запрос функции как Android bug 6322. К сожалению, у нас очень длинный список проблем с производительностью и корректностью, поэтому я не могу дать вам график, когда мы будем тратить время на эту проблему.
Есть несколько альтернатив, но все они требуют некоторой работы:
Запустите приложение на стандартном JVM и выполните все генерацию кода среды выполнения там. Сбросить .файлы классов из памяти в файлы, а затем запустите dx для этих файлов. Если вы достаточно сложны, вы можете интегрировать всю эту работу в свою сборку.
Включите инструмент DX с открытым исходным кодом в качестве библиотеки проектов и выполните его программно из вашего приложения, возможно, в загрузчике классов вашего приложения. Это раздует двоичный файл вашего приложения.
Есть ли способ загрузить dex файлы / байт-коды в приложение по адресу время выполнения?
Посмотрите на
DexFile
и ещеDexClassLoader
.
Соответствующий ответ предполагает Dexmaker для динамической генерации байт-кода Dalvik.
Я использовал ASM и BCEL для создания классов Java, а затем я преобразовал их в файлы Dex. Наконец, я создал файлы jar для динамической загрузки на устройство.
Вы можете проверить мой код :)
Если внутри какой - либо программы на C или C++ вы хотите загрузить и вызвать классы DEX, вы можете увидеть, как запускается виртуальная машина Dalvik, внутри AndroidRuntime-например, Framework/base/cmds/app_process/app_main.cpp:
status_t app_init(const char* className, int argc, const char* const argv[]) { LOGV("Entered app_init()!\n"); AndroidRuntime* jr = AndroidRuntime::getRuntime(); jr->callMain(className, argc, argv); LOGV("Exiting app_init()!\n"); return NO_ERROR; }
Поскольку" jr " AndroidRuntime уже запущен, callMain () будет вызван:
status_t AndroidRuntime::callMain( const char* className, int argc, const char* const argv[]) { JNIEnv* env; jclass clazz; jmethodID methodId; LOGD("Calling main entry %s", className); env = getJNIEnv(); if (env == NULL) return UNKNOWN_ERROR; clazz = findClass(env, className); if (clazz == NULL) { LOGE("ERROR: could not find class '%s'\n", className); return UNKNOWN_ERROR; } methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V"); if (methodId == NULL) { LOGE("ERROR: could not find method %s.main(String[])\n", className); return UNKNOWN_ERROR; } <...> env->CallStaticVoidMethod(clazz, methodId, strArray); return NO_ERROR; }
Сверху мы можем видеть, как загружаются коды классов DEX, и CallStaticVoidMethod() начнет интерпретировать коды DEX.