在Java里面,我们可以把一些类放到.jar文件里面,然后用ClassLoader动态加载。例如:

[java] view plain copy
  1. URLClassLoaderucl=URLClassLoader.newInstance(newURL[]
  2. {newURL("file:/sdcard/files/test.jar")});
  3. Classclazz=ucl.loadClass("com.test.TestClass");

但是在Android上面,情况有所不同。

首先第一个是jar文件的制作,Java里面直接把.class文件打包到.jar文件里面就可以了,但是Android 的DalvikVM是不认Java的bytecode 的,所以不能直接这么打包,而要用dx工具转成Dalvikbytecode才可以。当然,dx工具转了之后,jar包里面就不是.class文件了,而是.dex文件。关于这一点可以参考我的另外一篇文章:http://blog.csdn.net/quaful/archive/2010/12/23/6094940.aspx

第二个是,Android里面虽然也提供了URLClassLoader的实现,但是并不能用。要动态加载其它类,可以用的 ClassLoader有:

DexClassLoader

PathClassLoader

其中,DexClassLoader可以加载apk,jar或者dex文件,例如:

[java] view plain copy
  1. FilejarFile=newFile("/sdcard/test.dex");
  2. if(jarFile.exists()){
  3. DexClassLoadercl=newDexClassLoader(jarFile.toString(),"/sdcard/test",null,ClassLoader.getSystemClassLoader());
  4. Class<?>c=cl.loadClass("com.qihoo360.test.Test");
  5. ...
  6. }

但是DexClassLoader要求指定一个可写的目录,即DexClassLoader 构造函数的第二个参数,在上例中是/sdcard/test

这个参数的含义是:directory where optimized DEX files should be written

因为Dalvik在加载dex文件时,会动态进行优化,DexClassLoader要求指定优化后dex文件存放的位置。

PathClassLoader的限制要更多一些,它只能加载已经安装到Android系统中的apk文件,也就是/data/app目录下的apk文件。其它位置的文件加载的时候都会出现ClassNotFoundException.例如:

[java] view plain copy
  1. PathClassLoadercl=newPathClassLoader(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了。

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. AndroidICS4.0---->LockScreen锁屏流程【Android源码解析九】
  6. Android(安卓)代码中动态为RadioGroup添加RadioButton
  7. Android开发之实现锁屏功能
  8. Android本地代码直接访问远程数据库(Rxjava方式)
  9. Android(安卓)如何访问Assets文件夹里面的资源

随机推荐

  1. 在Android上使用Lambda表达式 - retrolam
  2. android studio设置Tab为四空格缩进
  3. android电量优化措施
  4. 解决OPPO手机adb调试找不到设备(Win8系统)
  5. 广播机制简介
  6. Android(安卓)获取 usb 权限
  7. 2020年的Android(安卓)虚拟机都可以这么
  8. cocos2d-x在Android真机上使用Sqlite
  9. Android蓝牙BLE基本用法
  10. android软件安全与逆向分析重打包签名出