Android remote code loading

Go To StackoverFlow.com

16

I am developing a library for Android that requires frequent updates from a central server. I was thinking how nice it would be if my library could update itself -- or if I could just release a bootstrap library that downloads the target library when the app is installed.

I see this class in 1.5 called "DexClassLoader" but there seems to be precious little on the web besides the API docs. Has anyone used this successfully for the scenario which I described?

Also, do the terms of the Android Market permit such a thing?

2009-06-16 14:43
by sehugg


13

I've successfully used DexClassLoader. It's important to provide a dexOutputDir that is actually writeable by your app, so not /data/dalvik-cache. Otherwise the log will show one or two lines about failing to write there, followed by ClassNotFoundException.

cl = new DexClassLoader("/full/path/com.example.apk",
                        getFilesDir().getAbsolutePath(),// /data/data/foo/files
                        null,  // native lib path, I haven't used this
                        MyClass.class.getClassLoader());
// This doesn't make Class.forName() work, instead I do this:
Class<?> foo = cl.loadClass("com.example.foo");

To make Class.forName() work, you could try Thread.setContextClassLoader() (I haven't).

2010-02-24 12:46
by Chris Boyle
Hello can you please add complete source code.It will be a great help.Thanks in advance - Harry Sharma 2015-10-14 13:18
it is not work for android5 lollipop and above because of ART: http://stackoverflow.com/questions/27349097/load-dex-file-dynamically-on-android-5- - gturedi 2016-03-18 21:36


3

Indeed what you want is supported and works. DexClassLoader is not working as expected for me, but the following code works fine.

DexFile df = new DexFile(new File("/data/app/my_downloaded_lib.apk"));
ClassLoader cl = getClassLoader();
Class clazz = df.loadClass("com/my/lib/MyClass", cl);

About the market question, i don't see any issue with this, but you have to read the EULA to be sure.

2009-06-16 22:54
by Lucas S.
This works, but making a File object is counterproductive: DexFile will take the path and open it itself. You could use the constructor that takes a String path - Chris Boyle 2010-02-24 12:35
Hello, maybe you are right, but when i answered, this was the only way it works - Lucas S. 2010-03-01 16:06


2

DexClassLoader is the right answer. Applications should never use DexFile directly (it's meant to be used by class loaders).

You could use external storage (/sdcard), or the app's private data area, for the dexOutputDir parameter. External storage is usually larger, but if the card is ejected your app will be killed, and due to the lack of file permission enforcement it's easy for a third party to replace your code. This can allow malicious apps to cause your app to perform arbitrary actions. (If you want to do it anyway, get the path via Environment.getExternalStorageDirectory(); requires the WRITE_EXTERNAL_STORAGE permission.)

The app-private data area (get the path from Context.getFilesDir()) is more secure, and also has the advantage of being cleaned up automatically if the app is uninstalled. This is the recommended approach.

2010-03-15 19:55
by fadden
I would also think that loading code off the SD card would be somewhat insecure - CommonsWare 2010-03-15 20:10
NEVER write your dex file to the SD Card path. This will create a security vulnerability. http://www.symantec.com/connect/blogs/android-class-loading-hijackin - ajma 2013-07-16 18:00
Updated to address security concerns - fadden 2013-07-16 18:24
Ads