Android插件化开发基础之App如何动态加载类
在 Java 里面,我们可以把一些类放到 .jar 文件里面,然后用 ClassLoader 动态加载。例如:
URLClassLoader ucl = URLClassLoader.newInstance(new URL[]
{new URL("file:/sdcard/files/test.jar")});
Class clazz = ucl.loadClass("com.test.TestClass");
但是在 Android 上面,情况有所不同。
首先第一个是 jar 文件的制作,Java 里面直接把 .class 文件打包到 .jar 文件里面就可以了,但是 Android 的 Dalvik VM 是不认 Java 的 byte code 的,所以不能直接这么打包,而要用 dx 工具转成 Dalvik byte code 才可以。当然,dx 工具转了之后,jar 包里面就不是 .class 文件了,而是 .dex 文件。关于这一点可以参考我的另外一篇文章:http://blog.csdn.NET/quaful/archive/2010/12/23/6094940.aspx
第二个是,Android 里面虽然也提供了 URLClassLoader 的实现,但是并不能用。要动态加载其它类,可以用的 Class Loader 有:
DexClassLoader
PathClassLoader
其中,DexClassLoader 可以加载 apk, jar 或者 dex 文件,例如:
File jarFile = new File("/sdcard/test.dex");
if ( jarFile.exists() ) {
DexClassLoader cl = new DexClassLoader(jarFile.toString(), "/sdcard/test", null, ClassLoader.getSystemClassLoader());
Class<?> c = cl.loadClass("com.qihoo360.test.Test");
...
}
但是 DexClassLoader 要求指定一个可写的目录,即 DexClassLoader 构造函数的第二个参数,在上例中是 /sdcard/test
这个参数的含义是:directory where optimized DEX files should be written
因为 Dalvik 在加载 dex 文件时,会动态进行优化,DexClassLoader 要求指定优化后 dex 文件存放的位置。
PathClassLoader 的限制要更多一些,它只能加载已经安装到 Android 系统中的 apk 文件,也就是 /data/app 目录下的 apk 文件。其它位置的文件加载的时候都会出现 ClassNotFoundException. 列如:
PathClassLoader cl = new PathClassLoader(jarFile.toString(), "/data/app/", ClassLoader.getSystemClassLoader());
为什么有这个限制呢?我认为这其实是当前 Android 的一个 bug, 因为 PathClassLoader 会去读取 /data/dalvik-cache 目录下的经过 Dalvik 优化过的 dex 文件,这个目录的 dex 文件是在安装 apk 包的时候由 Dalvik 生成的。例如,如果包的名字是 com.qihoo360.test,Android 应用安装之后都保存在 /data/app 目录下,即 /data/app/com.qihoo360.test-1.apk,那么 /data/dalvik-cache 目录下就会生成 data@app@com.qihoo360.test-1.apk@classes.dex 文件。在调用 PathClassLoader 时,它就会按照这个规则去找 dex 文件,如果你指定的 apk 文件是 /sdcard/test.apk,它按照这个规则就会去读 /data/dalvik-cache/sdcard@test.apk@classes.dex 文件,显然这个文件不会存在,所以 PathClassLoader 会报错。
在 Google 修正这个问题之前,我们要么就只能用 DexClassLoader,要么就只能用 PathClassLoader 加载已安装的 apk 了。
Android插件化开发基础之App如何动态加载类相关推荐
- Android插件化开发基础之Java类加载器与双亲委派模型
类加载器 Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需 ...
- 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图...
如果你使用过一些开源CMS的话,肯定会用过其中的的插件化功能,用户可以通过启用或者上传插件包的方式动态添加一些功能,那么在ASP.NET Core MVC中如何实现插件化开发呢,下面我们来探究一下. ...
- Android插件化开发基础之Java动态代理(proxy)机制的简单例子
一.代码 package com.sangfor.tree;import java.lang.reflect.InvocationHandler; import java.lang.reflect.M ...
- Android插件化开发基础之静态代理模式
一 Proxy模式 意图: 为其他对象提供一种代理以控制这个对象的访问. 适用性: l 远程代理( Remote Proxy ): 为一个对象在不同的地址空间提供局部代表. l 虚代理(Virtu ...
- Android插件化开发基础之Java反射机制研究
一.获得Class对象 Class<?> c = Class.forName("classname"); 抛出ClassNotFoundException 二.获得实现 ...
- Android插件化开发之动态加载基础之ClassLoader工作机制
类加载器ClassLoader 早期使用过Eclipse等Java编写的软件的同学可能比较熟悉,Eclipse可以加载许多第三方的插件(或者叫扩展),这就是动态加载.这些插件大多是一些Jar包,而使用 ...
- Android插件化开发之动态加载技术简单易懂的介绍方式
转载地方:https://segmentfault.com/a/1190000004062866 基本信息 Author:kaedea GitHub:android-dynamical-loading ...
- Android插件化开发指南——Hook技术(一)【长文】
文章目录 1. 前言 2. 将外部dex加载到宿主app的dexElements中 3. 插件中四大组件的调用思路 4. Hook 2.1 对startActivity进行Hook 2.1.1 AMS ...
- Android插件化开发之动态加载本地皮肤包进行换肤
Android插件化开发之动态加载本地皮肤包进行换肤 前言: 本文主要讲解如何用开源换肤框架 android-skin-loader-lib来实现加载本地皮肤包文件进行换肤,具体可自行参考框架原理进行 ...
最新文章
- OneinStack一键部署操作说明
- Syszuxpin中文输入法移植
- ​AAAI 2022 | 基于强化学习的视频弹幕攻击
- video.js html5 视频播放器
- [蓝桥杯2016初赛]卡片换位-bfs
- 8.19noip模拟题
- 谷歌发布最新版安卓Android,谷歌发布安卓 9 正式版,代号 Android Pie
- python调用arcpy函数_python笔记之ArcPy函数列表
- gp3688 uhf2扩频_摩托罗拉GP3688对讲机(VHF、UHF)对讲机维修
- range函数--python内置函数
- Unity3d iOS 内购详细流程总汇
- 并行计算 SLIC超像素算法(二) 代码分析
- 如何安装Win10/Ubuntu双系统
- 光纤信号服务器,485转光纤的两种方式
- 织梦php环境搭建,织梦建站入门:搭建本地PHP环境图文教程
- 深造分布式 打败面试官 招式三 直捣黄龙
- tomcat的开发模式和生产模式
- NP 10抗菌肽是什么?有什么作用?
- C#中word文档转html
- 项目训练营模块学习---Oled屏幕
热门文章
- Dapr 客户端 搭配 WebApiClientCore 玩耍服务调用
- dotnet 是 前30个增长最快速度的开源项目中排名第一的开发平台
- Apache Member、ALC Beijing 发起人姜宁:一个人走的很快,但是一群人能走得更远
- ML.NET Cookbook:(3)如何从CSV加载包含多个列的数据?
- 学习搭建 Consul 服务发现与服务网格-有丰富的示例和图片
- BeetleX之HTTP网关部署
- 继续分享 5 个实用的 vs 调试技巧
- DevOps vs. Agile:它们有什么共同点?
- Asp.Net.Core WebApi 版本控制
- 小cookie,大智慧