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

发布于 2024-08-29 01:45:32 字数 111 浏览 7 评论 0原文

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

谢谢

This question has been asked(and answered) many times about dynamically generating and loading java bytecodes at runtime into a running Dalvik VM, but is there any way to load dex files/bytecodes into an app at runtime?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

看春风乍起 2024-09-05 01:45:33

Dalvik 团队希望构建一个一流的运行时代码生成库。我们正在将功能请求跟踪为 Android bug 6322。不幸的是,我们有一个很长的性能和正确性问题列表,因此我无法向您提供我们何时花时间解决此问题的时间表。

有一些替代方案,但它们都需要一些工作:

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

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

The Dalvik team would like to build a first-class runtime code generation library. We're tracking the feature request as Android bug 6322. Unfortunately, we have a very long list of performance and correctness issues, so I can't give you a timeline for when we'll spend time on this issue.

There are some alternatives, but they will all take some work:

  • Run your application on a standard JVM and exercise all runtime code generation there. Dump the .class files from memory to files, and then run dx on those files. If you're quite sophisticated, you could integrate all of this work into your build.

  • Include the open source dx tool as a project library, and execute it programatically from within your application, possibly in your application's classloader. This will bloat your application's binary.

夏有森光若流苏 2024-09-05 01:45:33

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

查看 DexFileDexClassLoader

is there any way to load dex
files/bytecodes into an app at
runtime?

Look at DexFile and DexClassLoader.

想你的星星会说话 2024-09-05 01:45:33

相关答案建议Dexmaker 用于动态 Dalvik 字节码生成。

A related answer suggests Dexmaker for dynamic Dalvik bytecode generation.

月下凄凉 2024-09-05 01:45:33

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

你可以查看我的代码:)

https://github.com/sciruela/android

I have used ASM and BCEL to generate Java classes and then I have converted them to Dex files.
Finally I have created jar files to load dynamically on device.

You can check out my code :)

https://github.com/sciruela/android

凑诗 2024-09-05 01:45:33

如果在任何 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;
}

: " 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 代码。

If inside any C or C++ program, you want to load and call into the DEX classes, you can see how the Dalvik VM is started, inside the AndroidRuntime - for example 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;
}

As "jr" AndroidRuntime is already started, callMain() will be called:

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;
}

From above, we can see how the DEX classes' codes are loaded and CallStaticVoidMethod() will start interpreting the DEX codes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文