在 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如何动态加载类相关推荐

  1. Android插件化开发基础之Java类加载器与双亲委派模型

    类加载器 Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需 ...

  2. 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图...

    如果你使用过一些开源CMS的话,肯定会用过其中的的插件化功能,用户可以通过启用或者上传插件包的方式动态添加一些功能,那么在ASP.NET Core MVC中如何实现插件化开发呢,下面我们来探究一下. ...

  3. Android插件化开发基础之Java动态代理(proxy)机制的简单例子

    一.代码 package com.sangfor.tree;import java.lang.reflect.InvocationHandler; import java.lang.reflect.M ...

  4. Android插件化开发基础之静态代理模式

    一 Proxy模式 意图: 为其他对象提供一种代理以控制这个对象的访问. 适用性: l  远程代理( Remote Proxy ): 为一个对象在不同的地址空间提供局部代表. l  虚代理(Virtu ...

  5. Android插件化开发基础之Java反射机制研究

    一.获得Class对象 Class<?> c = Class.forName("classname"); 抛出ClassNotFoundException 二.获得实现 ...

  6. Android插件化开发之动态加载基础之ClassLoader工作机制

    类加载器ClassLoader 早期使用过Eclipse等Java编写的软件的同学可能比较熟悉,Eclipse可以加载许多第三方的插件(或者叫扩展),这就是动态加载.这些插件大多是一些Jar包,而使用 ...

  7. Android插件化开发之动态加载技术简单易懂的介绍方式

    转载地方:https://segmentfault.com/a/1190000004062866 基本信息 Author:kaedea GitHub:android-dynamical-loading ...

  8. Android插件化开发指南——Hook技术(一)【长文】

    文章目录 1. 前言 2. 将外部dex加载到宿主app的dexElements中 3. 插件中四大组件的调用思路 4. Hook 2.1 对startActivity进行Hook 2.1.1 AMS ...

  9. Android插件化开发之动态加载本地皮肤包进行换肤

    Android插件化开发之动态加载本地皮肤包进行换肤 前言: 本文主要讲解如何用开源换肤框架 android-skin-loader-lib来实现加载本地皮肤包文件进行换肤,具体可自行参考框架原理进行 ...

最新文章

  1. OneinStack一键部署操作说明
  2. Syszuxpin中文输入法移植
  3. ​AAAI 2022 | 基于强化学习的视频弹幕攻击
  4. video.js html5 视频播放器
  5. [蓝桥杯2016初赛]卡片换位-bfs
  6. 8.19noip模拟题
  7. 谷歌发布最新版安卓Android,谷歌发布安卓 9 正式版,代号 Android Pie
  8. python调用arcpy函数_python笔记之ArcPy函数列表
  9. gp3688 uhf2扩频_摩托罗拉GP3688对讲机(VHF、UHF)对讲机维修
  10. range函数--python内置函数
  11. Unity3d iOS 内购详细流程总汇
  12. 并行计算 SLIC超像素算法(二) 代码分析
  13. 如何安装Win10/Ubuntu双系统
  14. 光纤信号服务器,485转光纤的两种方式
  15. 织梦php环境搭建,织梦建站入门:搭建本地PHP环境图文教程
  16. 深造分布式 打败面试官 招式三 直捣黄龙
  17. tomcat的开发模式和生产模式
  18. NP 10抗菌肽是什么?有什么作用?
  19. C#中word文档转html
  20. 项目训练营模块学习---Oled屏幕

热门文章

  1. Dapr 客户端 搭配 WebApiClientCore 玩耍服务调用
  2. dotnet 是 前30个增长最快速度的开源项目中排名第一的开发平台
  3. Apache Member、ALC Beijing 发起人姜宁:一个人走的很快,但是一群人能走得更远
  4. ML.NET Cookbook:(3)如何从CSV加载包含多个列的数据?
  5. 学习搭建 Consul 服务发现与服务网格-有丰富的示例和图片
  6. BeetleX之HTTP网关部署
  7. 继续分享 5 个实用的 vs 调试技巧
  8. DevOps vs. Agile:它们有什么共同点?
  9. Asp.Net.Core WebApi 版本控制
  10. 小cookie,大智慧