loading of classes in your Android app

原文的地址:我正在编写一个应用程序能够加载别人开发的应用插件。对于应用程序思路的实现,我首先想到的是使用 Class.forName 以及java.lang.reflective中的提供的方法。我比较倾向于使用 Class.forName(),像下面一样:

try {Class<?> handler = Class.forName(handlerClassName);Method m = handler.getDeclaredMethod("addMyPreferences",Class.forName("android.content.Context"),Class.forName("android.preference.PreferenceCategory"),Class.forName("java.lang.String"));m.invoke(handler.newInstance(), this, mExtraSettingsCategory, defaultValue);} catch(ClassNotFoundException e) {// …..}// other exceptions that may be thrown by reflective API.但是经过实践发现,上面的代码会出现ClassNotFoundException的异常。我怎么办?一个比较麻烦的问题在我的脑海里闪现,我猜想是不是别的开发者也会和我遇到同样的问题,于是我就谷歌查询,发现一个文档对我理解:为什么上面的代码会抛出ClassNotFoundException异常非常有帮助(点击这里)。该文档上说,Java的基本动态加载模块依赖于java的parent-chaild层次结构和ClassLoader类。通过日志打印出类加载的顺序(层次)对于理解类的加载很有帮助。因此,我就这么做了。ClassLoader cl = this.getClass().getClassLoader();while (cl != null) {Log.d(TAG, "====> class loader: " + cl.getClass());cl = cl.getParent();}

在我的电脑上,在类加载的时候打印显示加载了2个类分别是 dalvik.system.PathClassLoader类 和 java.lang.BootClassLoader类。最有趣的事情是使用 PathClassLoader类。查看它的文档发现 PathClassLoader类能够接受不同类型的值作为它的构造函数的参数,,直接从文档上复制过来看:public PathClassLoader (String path, ClassLoader parent)Creates a PathClassLoader that operates on a given list of files and directories. This method is equivalent to calling PathClassLoader(String, String, ClassLoader) with a null value for the second argument (see description there).* Directories containing classes or resources.* JAR/ZIP/APK files, possibly containing a "classes.dex" file.* "classes.dex" files.

好啦,基于文档上面的规定说明,我猜测使用apk文件名构造PathClassLoader 类实例,并且这个apk应用是在传递中创建,如下:PathClassLoader("/data/app/org.startsmall.myapp.apk",ClassLoader.getSystemClassLoader());因此,如果我想使用Class.forName()就应该从第三方应用开发者哪里知道要加载的类的名字,并且必须重新构造PathClassLoader 类实例从我的apk应用和第三方应用中加载类,下面是示例代码:final String apkFiles ="/data/app/org.startsmall.myapp.apk:" + // myself// handlers defined by other developers"/data/app/" + handlerClassName.substring(0, lastDotPos) + ".apk";dalvik.system.PathClassLoader myClassLoader =new dalvik.system.PathClassLoader(apkFiles,ClassLoader.getSystemClassLoader());// …try {Class<?> handler =Class.forName(handlerClassName, true, classLoader);// Call reflective APIs.} catch (ClassNotFoundException e) {// …..}经过上面这些经验和错误,我的代码终于可以加载第三方的类和方法,并且可以执行达到预期的效果。

注:翻译的不好,请无视直接看原文。

要么读书、要么旅行,灵魂和身体,必须有一个在路上。

loading of classes in your Android app

相关文章:

你感兴趣的文章:

标签云: