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

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

Спасибо

Ответы [ 5 ]

23 голосов
/ 10 апреля 2010

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

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

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

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

5 голосов
/ 10 апреля 2010

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

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

3 голосов
/ 21 мая 2012

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

2 голосов
/ 27 января 2012

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

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

https://github.com/sciruela/android

1 голос
/ 09 февраля 2011

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

Поскольку AndroidRuntime "jr" уже запущен, вызывается 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.

...