在Android的App中动态的加载Java类
原文的地址: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类的更多相关文章
- 使用javassist运行时动态重新加载java类及其他替换选择
在不少的情况下,我们需要对生产中的系统进行问题排查,但是又不能重启应用,java应用不同于数据库的存储过程,至少到目前为止,还不能原生的支持随时进行编译替换,从这种角度来说,数据库比java的动态性要 ...
- 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?
Java虚拟机是如何加载Java类的? 这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...
- Android系统下的动态Dex加载与app速度优化
1 问题 在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把 ...
- Android系统下的动态Dex加载
1 问题在Android系统中,一个App的所有代码都在一个Dex文件里面.Dex是一个类似Jar的存储了多有Java编译字节码的归档文件.因为Android系统使用Dalvik虚拟机,所以需要把使用 ...
- 03 Java 虚拟机是如何加载 Java 类的
Java 引用类型 Java 中的引用类型细分为四种:类,接口,数组类和泛型参数. 因为泛型参数会在编译过程中被擦除,所以 Java 虚拟机实际上只有前三种.数组类是由 Java 虚拟机直接生成的,其 ...
- 怎么在 html 中 动态的加载一个 script
var script = document.createElement( 'script' );script.type = 'text/javascript';script.src = bodyStr ...
- log4j中Logger.getLogger()加载一个类提示错误
转载自:https://blog.csdn.net/q3229270/article/details/77986687 ----------------------------- 错误提示如下:The ...
- IDEA 配置Jrebet 自动加载Java类,
官方文档地址: http://manuals.zeroturnaround.com/jrebel/ide/intellij.html#installation 过期激活 https://blog.cs ...
- Java_动态重新加载Class总结
在此记载Java动态重新加载Class的点点滴滴,实现之前也在网上看了很多文章,但发现不是很清晰,后来发现总结,看源码实现还是最靠谱. 直接上代码: package com.lkb.autoCode. ...
随机推荐
- [译]我是如何将GTA在线模式的加载时间缩短70%的
[译]我是如何将GTA在线模式的加载时间缩短70%的 译注: 最近在网上发现了一篇有意思的文章, 一个国外大神受不了GTA5在线模式的加载时间, 一怒之下反汇编了GTA5的源码, 并最终发现了问题的原 ...
- python获取到本机的公网IP
5行代码获取到本机的公网IP from urllib.request import urlopen import re text = str(urlopen("http://txt.go.s ...
- C# 应用 - 使用 HttpClient 发起上传文件、下载文件请求
1. 示例代码 using System; using System.IO; using System.Net.Http; /// <summary> /// 下载文件 /// </ ...
- redhat安装python3.7
下载并解压: 1 wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz 2 tar -xzvf Python-3.7.2.tgz ...
- CRLF注入
CRLF注入 Title: [CVE-2019-9740] Python urllib CRLF injection vulnerability Category: security Stage: r ...
- 常用开发库 - MapStruct工具库详解
常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...
- JS 字符数组和数字数组转换
var newArr = ['1','2','3'].map(Number):// [1,2,3] var newArr =[1,2,3].map(String):// ['1','2','3']
- (数据科学学习手札114)Python+Dash快速web应用开发——上传下载篇
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- 手机浏览器通过Scheme跳转APP,兼容各种手机浏览器
一个比较完整的产品线,必定有APP和网站,另外还有微信公众号网页和小程序.那么有一个比较常见的需求就是在手机浏览器内打开APP,实现起来也比较简单,只要APP配置的有URLScheme即可. 但是因为 ...
- " "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问>
" "( 双引号) 与 ' '( 单引号) 差在哪?-- Shell十三问<第四问> 经过前面两章的学习,应该很清楚当你在 shell prompt 后面敲打键盘.直到 ...