动态生成Dalvik字节码到运行的Dalvik / Android应用程序

时间:2010-04-09 21:16:59

标签: android dalvik

这个问题多次被问及(并回答)关于在运行时动态生成和加载java字节码到运行的Dalvik VM,但有没有办法在运行时将dex文件/字节码加载到应用程序中?

由于

5 个答案:

答案 0 :(得分:23)

Dalvik团队希望构建一流的运行时代码生成库。我们正在跟踪功能请求Android bug 6322。不幸的是,我们有很长的性能和正确性问题清单,所以我不能给你一个时间表来说明我们何时会花时间处理这个问题。

有一些选择,但他们都会做一些工作:

  • 在标准JVM上运行您的应用程序,并在那里运行所有运行时代码。将.class文件从内存转储到文件,然后在这些文件上运行dx。如果你非常复杂,你可以将所有这些工作集成到你的构建中。

  • 将开源dx工具作为项目库包含在内,并从应用程序中以编程方式执行,可能在应用程序的类加载器中。这会使应用程序的二进制文件膨胀。

答案 1 :(得分:5)

  

有没有办法加载dex   文件/字节码到应用程序中   运行

查看DexFileDexClassLoader

答案 2 :(得分:3)

A related answer建议Dexmaker生成动态Dalvik字节码。

答案 3 :(得分:2)

我使用ASM和BCEL生成Java类,然后我将它们转换为Dex文件。 最后,我创建了jar文件,以便在设备上动态加载。

您可以查看我的代码:)

https://github.com/sciruela/android

答案 4 :(得分:1)

如果在任何C或C ++程序中,您想要加载并调用DEX类,您可以在AndroidRuntime中查看Dalvik VM的启动方式 - 例如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代码。