原文的地址:http://yenliangl.blogspot.com/2009/11/dynamic-loading-of-classes-in-your.html

我正在编写一个应用程序能够加载别人开发的应用插件。对于应用程序思路的实现,我首先想到的是使用 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) {
// .....
}

经过上面这些经验和错误,我的代码终于可以加载第三方的类和方法,并且可以执行达到预期的效果。

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

在Android的App中动态的加载Java类的更多相关文章

  1. 使用javassist运行时动态重新加载java类及其他替换选择

    在不少的情况下,我们需要对生产中的系统进行问题排查,但是又不能重启应用,java应用不同于数据库的存储过程,至少到目前为止,还不能原生的支持随时进行编译替换,从这种角度来说,数据库比java的动态性要 ...

  2. 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?

    Java虚拟机是如何加载Java类的?  这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...

  3. Android系统下的动态Dex加载与app速度优化

    1 问题 在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把 ...

  4. Android系统下的动态Dex加载

    1 问题在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把使用 ...

  5. 03 Java 虚拟机是如何加载 Java 类的

    Java 引用类型 Java 中的引用类型细分为四种:类,接口,数组类和泛型参数. 因为泛型参数会在编译过程中被擦除,所以 Java 虚拟机实际上只有前三种.数组类是由 Java 虚拟机直接生成的,其 ...

  6. 怎么在 html 中 动态的加载一个 script

    var script = document.createElement( 'script' );script.type = 'text/javascript';script.src = bodyStr ...

  7. log4j中Logger.getLogger()加载一个类提示错误

    转载自:https://blog.csdn.net/q3229270/article/details/77986687 ----------------------------- 错误提示如下:The ...

  8. IDEA 配置Jrebet 自动加载Java类,

    官方文档地址: http://manuals.zeroturnaround.com/jrebel/ide/intellij.html#installation 过期激活 https://blog.cs ...

  9. Java_动态重新加载Class总结

    在此记载Java动态重新加载Class的点点滴滴,实现之前也在网上看了很多文章,但发现不是很清晰,后来发现总结,看源码实现还是最靠谱. 直接上代码: package com.lkb.autoCode. ...

随机推荐

  1. 转: 微信已支持发送最大 200MB 的视频了,并且不会被压缩 来自腾讯微信团队的视频消息,目前 iOS 版本的微信已支持发送最大 200MB 的视频与图片了,并且不会被压缩.安卓版本未来一段时间会支 ...

  2. HDOJ-3746(KMP+最小循环结)

    Cyclic Nacklace HDOJ-3746 本题还是使用KMP算法,需要使用到前缀数组 利用前缀数组计算最小循环节:即t=n-pi[n-1]. 最后输出还需要的珠子,当然还有判断什么时候输出为 ...

  3. AI在出行场景的应用实践:路线规划、ETA、动态事件挖掘…

    ​前言:又到春招季!作为国民级出行服务平台,高德业务快速发展,大量校招/社招名额开放,欢迎大家投递简历,详情见文末.为帮助大家更了解高德技术,我们策划了#春招专栏#的系列文章,组织各业务团队的高年级同 ...

  4. CVE-2017-12149-JBoss 5.x/6.x 反序列化

    漏洞分析 https://www.freebuf.com/vuls/165060.html 漏洞原理 该漏洞位于JBoss的HttpInvoker组件中的 ReadOnlyAccessFilter 过 ...

  5. 趣谈 DHCP 协议,有点意思。

    计算机网络我也连载了很多篇了,大家可以在我的公众号「程序员cxuan」 或者我的 github 系统学习. 计算机网络第一篇,聊一聊网络基础 :计算机网络基础知识总结 计算机网络第二篇,聊一聊 TCP ...

  6. 任务3 PHP配置 1. PHP基础配置

    查看PHP配置文件得位置 #/ucsr/local/php/bin/php -i |grep -i "loaded configuration file" # cp /usr/lo ...

  7. 前端笔记:React的form表单全部置空或者某个操作框置空的做法

    1.全部置空的做法,一般在弹出框关闭后,需要重置该form所有表单: this.props.form.resetFields(); 2.针对某个操作框置空的做法 例如,form表单里有一个部门和一个张 ...

  8. ARFoundation - 实现物体旋转, 平移,缩放

    ARFoundation - 实现物体旋转, 平移,缩放 本文目的是为了确定在移动端怎样通过单指滑动实现物体的旋转,双指实现平移和缩放. 前提知识: ARFoundation - touch poin ...

  9. 「HTML+CSS」--自定义按钮样式【001】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  10. LevelDB 源码解析之 Random 随机数

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...