Android remote code loading

后端 未结 3 985
孤街浪徒
孤街浪徒 2020-12-07 11:08

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

相关标签:
3条回答
  • 2020-12-07 11:25

    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.

    0 讨论(0)
  • 2020-12-07 11:27

    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.

    0 讨论(0)
  • 2020-12-07 11:33

    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).

    0 讨论(0)
提交回复
热议问题