Prior to Android 5.0 I was able to load DEX files dynamically using DexClassLoader and calling loadClass()
method but with the latest Android version I get a ClassNotFoundException
.
Here is what I am doing:
Generate DEX file.
../android-sdk/android-sdk-linux_86/build-tools/21.1.1/dx --dex --output=bin/output.dex bin/output.jar
Create a DexClassLoader.
DexClassLoader cl = new DexClassLoader( dexFile.getAbsolutePath(), odexFile.getAbsolutePath(), null, mContext.getClassLoader());
Call
cl.loadClass("myMethod");
I am aware that ART uses dex2oat to generate an ELF file that is the loaded by ART but in step 2 I am generating an ODEX file so I am not what needs to be done in ART to load a DEX file at runtime, can anyone help me ?
Update
This works both on Dalvik and ART:
new DexClassLoader(jarredDex.getAbsolutePath(), context.getDir("outdex", Context.MODE_PRIVATE).getAbsolutePath(), null, context.getClassLoader());
wherejarredDex
is a jar-file withclasses.dex
. Jar can be obtained by runningdx --dex --output=filename.jar your/classes/dir
.Original answer
I've took a code sample from this article. But ART uses
PathClassLoader
instead of Dalvik'sDexClassLoader
. This code is tested on emulator with Android 6 and on Xiaomi with Android 5.1 and works fine:It is the problem with making dex file. Change the command as below then will work in all versions of android.
The above method in windows will generate a .jar file with classes.dex file inside that jar file. The DexClassLoader is searching for classes.dex file inside, that is why it is throwing ClassNotFoundException