I am currently developing a distributed system whose nodes are able to download jar and dex files from a server to change their behavior at runtime. Not-Android nodes add jars using the following code to invoke addURL method provided by ClassLoader:
File f = new File(fileName);
URL u = f.toURI().toURL();
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<?> sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[] { u });
} catch (Throwable t) { }
Is it possible to do the same with a dex file on an Android node? DexClassLoader and PathClassLoader do not provide a method such as addURL. I know I can add single classes using reflection, but I don't know how to add the whole dex file. The problem is that if I add all the classes in the dex one by one, I get exceptions for missing dependencies. This is because a class may depend on another which still has to get added. Anyway the code I use to add single classes is the following.
File f = new File(pathToSaveFile + dexFile);
Object obj = null;
final File optimizedDexOutputPath = context.getDir("outdex", 0);
DexClassLoader classLoader = new DexClassLoader(
f.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null,
context.getClassLoader());
String path = pathToSaveFile + dexFile;
try {
DexFile dx = DexFile.loadDex(
path,
File.createTempFile("opt", "dex", context.getCacheDir()).getPath(),
0);
Class<?> myClass = classLoader.loadClass(className);
} catch (Exception e) { }
I am aware of the security issues in performing dynamic code offloading, but this is just a research project.
Try code in https://gist.github.com/nickcaballero/7045993
This method kind of appends your newly created DexClassLoader to the existing one.
Note it uses reflection so it may not work for all Android version. At least it works on my SDK19.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With