Подтвердить что ты не робот

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

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

Спасибо

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Посмотрите DexFile и DexClassLoader.

Ответ 4

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

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

https://github.com/sciruela/android

Ответ 5

Если внутри любой программы на C или С++ вы хотите загрузить и вызвать классы DEX, вы можете увидеть, как запускается виртуальная машина Dalvik, в AndroidRuntime - например, frameworks/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.