25

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

Michael Kohout
  • 1,073
  • 1
  • 14
  • 26

5 Answers5

23

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.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • 1
    Thanks for your answer. Is there anything preventing me from writing my own code generator right now? I've written one for .Net->Flash and .Net->.Net, and Dex is like a cross between Java .Class and Flash .ABC files. Also, thanks for the link. I starred it and added a comment(requesting it's API be similar to .Net's DLR). – Michael Kohout Apr 12 '10 at 03:21
  • 3
    You could definitely write your own code generator right now. If you give it an Apache-license, even better! – Jesse Wilson Apr 14 '10 at 03:04
  • 3
    Update: take a look at dexmaker which makes this easy: http://code.google.com/p/dexmaker/ – Jesse Wilson Jan 27 '12 at 19:48
  • What are the chances of such a library being released now that Android is switching to ART? Will that even be possible with the new execution model? – lxgr May 19 '14 at 13:34
  • @lxgr See this related question: http://stackoverflow.com/questions/23739261/does-android-art-support-runtime-dynamic-class-loading-just-like-dalvik – Rafael Winterhalter Jul 30 '14 at 08:17
5

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

Look at DexFile and DexClassLoader.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    Previously on this topic: http://stackoverflow.com/questions/1001944/android-remote-code-loading/2450049#2450049 – fadden Apr 09 '10 at 23:56
3

A related answer suggests Dexmaker for dynamic Dalvik bytecode generation.

Community
  • 1
  • 1
Tony the Pony
  • 40,327
  • 71
  • 187
  • 281
2

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

Sergio
  • 780
  • 1
  • 9
  • 28
1

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.

Peter Teoh
  • 6,337
  • 4
  • 42
  • 58