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之常见帮助类的里面的函数和
- 下一篇: Android插件化开发之动态加载技术系