Динамическая генерация байт-кода Dalvik в работающее приложение Dalvik / Android


Этот вопрос был задан(и получил ответ) много раз о динамическом генерировании и загрузке байт-кодов java во время выполнения в работающую виртуальную машину Dalvik, но есть ли способ загрузить файлы dex/байт-коды в приложение во время выполнения?

Спасибо

5 25

5 ответов:

Команда Dalvik хотела бы создать первоклассную библиотеку генерации кода во время выполнения. Мы отслеживаем запрос функции как Android bug 6322. К сожалению, у нас очень длинный список проблем с производительностью и корректностью, поэтому я не могу дать вам график, когда мы будем тратить время на эту проблему.

Есть несколько альтернатив, но все они требуют некоторой работы:

  • Запустите приложение на стандартном JVM и выполните все генерацию кода среды выполнения там. Сбросить .файлы классов из памяти в файлы, а затем запустите dx для этих файлов. Если вы достаточно сложны, вы можете интегрировать всю эту работу в свою сборку.

  • Включите инструмент DX с открытым исходным кодом в качестве библиотеки проектов и выполните его программно из вашего приложения, возможно, в загрузчике классов вашего приложения. Это раздует двоичный файл вашего приложения.

Есть ли способ загрузить dex файлы / байт-коды в приложение по адресу время выполнения?

Посмотрите на DexFile и еще DexClassLoader.

Соответствующий ответ предполагает Dexmaker для динамической генерации байт-кода Dalvik.

Я использовал ASM и BCEL для создания классов Java, а затем я преобразовал их в файлы Dex. Наконец, я создал файлы jar для динамической загрузки на устройство.

Вы можете проверить мой код :)

Https://github.com/sciruela/android

Если внутри какой - либо программы на 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.