Android虛擬機的動態加載技術分爲兩種:一種是加載基於NDK的so庫;另外一種是加載用java語言開發的zip包。我今天主要討論後者。 java
先簡單說明一下so庫加載。NDK的執行效率很高,加密性很好,但同時開發入門難度大,通常用於加解密、數學運算等場合。so的加載很簡單,若是APK發佈時已經攜帶了so文件,只須要在加載時調用System.loadLibrary(libName)方法便可。因爲軟件的安裝目錄中存放so的目錄是沒有寫權限的,開發者不能更改該目錄的內容,因此若是要動態加載存放在其餘地方的so文件,用System.load(pathName)方法便可。 android
如今咱們重點來看一下如何用java開發android的動態包。之因此前面稱之爲zip包,是由於jar和apk其實都是zip格式的。android虛擬機支持這兩種文件後綴的包。android虛擬機支持加載zip包中的dex格式的代碼文件。因此咱們要用到一個很重要的類DexClassLoader,這個類是動態加在技術的關鍵。提到動態加載,還須要用到的一個就是java的反射技術,下面就舉一個調用僞代碼:
網絡
DexClassLoader dcl = new DexClassLoader(zip文件所在絕對路徑, zip文件所在目錄, 默認加載so所在目錄,Context包含的classLoader);
Class<?> clazz = dcl.loadClass(想要加載類的完整包名);
Method getInstance = clazz .getMethod(方法名, 參數類);
getInstance.invoke(null, 參數); //第一個參數爲null表示是靜態方法 加密
這樣就把zip文件中的類加載起來了,圖片等資源也能夠放在zip包中加載。有了這個技術,不少的執行邏輯能夠經過網絡下載的方式動態調整,實現了應用的多樣性。 spa
不過動態加載是有一些限制的,好比zip包中的Activity、Service類是不能動態加載的,由於缺乏聲明;即便你在Manifest文件中進行了聲明,系統默認也是到安裝apk所在的路徑中去尋找類,因此你會遇到一個ClassNotFound的異常。插件裏你能夠用apk中先前放入的layout、strings等資源。可是插件中自帶的界面只能用純代碼進行編寫,插件中是不能加載zip包中的xml做爲layout等資源使用的。因此在開發上一些特效會比較困難些,建議預先植入apk中。 插件
對於Activity、Service的動態加載,有一種變通的方法來解決,那就是在apk開發的時候預留各類Activity、Service的包裝類,定義最經常使用的處理event的方法,而後在事件處理的時候調用插件內定義的方法便可。 命令行
zip插件的製做:將代碼和資源導出成jar文件。一般在這一步的基礎上咱們用混淆器對代碼進行一次混淆。最後經過命令行dx命令將jar中的class文件轉換成dex文件。
xml