最近在了解公司的項目,第一次接觸Android插件化,了解其重要性,於是就開始了插件化的學習。本篇文章把插件化入門過程中的一些技術點整理下來,方便一些初入門的同學一起學習。

一、Android插件化介紹

1.含義

所謂插件化,就是讓我們的應用不必再像原來一樣把所有的內容都放在一個apk中,可以把一些功能和邏輯單獨抽出來放在插件apk中,然後主apk做到[按需調用],這樣的好處是一來可以減少主apk的體積,讓應用更輕便,二來可以做到熱插拔,更加動態化。

2.背景

3.優點

二、Android插件化基礎

1.插件化的特點

  1. 應用在運行的時候通過載入一些本地不存在的可執行文件實現一些特定的功能;
  2. 這些可執行文件是可以替換的;
  3. 更換靜態資源(比如換啟動圖、換主題、或者用伺服器參數開關控制廣告的隱藏現實等)不屬於動態載入;
  4. Android中動態載入的核心思想是動態調用外部的 dex文件,極端的情況下,Android APK自身帶有的Dex文件只是一個程序的入口(或者說空殼),所有的功能都通過從伺服器下載最新的Dex文件完成;

2.需要解決的問題

代碼載入

類的載入可以使用Java的ClassLoader機制,但是對於Android來說,並不是說類載入進來就可以用了,很多組件都是有「生命」的;因此對於這些有血有肉的類,必須給它們注入活力,也就是所謂的組件生命周期管理;

資源載入

資源載入方案大家使用的原理都差不多,都是用AssetManager的隱藏方法addAssetPath。

3.插件化必備基礎

①ClassLoader類載入器

要想實現載入外部dex文件(即插件)來實現熱部署,那麼必然要把其中的class文件載入到內存中。

其中涉及到兩種ClassLoader:DexClassLoader和PathClassLoader。而DexClassLoader可以載入外部的jar,dex等文件,正是我們需要的。

關於ClassLoader詳解,見ClassLoader完全解析。

②Java反射

因為插件apk與宿主apk不在一個apk內,那麼一些類的訪問必然要通過反射進行獲取。所以了解反射對插件化的學習是必須的。

關於Java反射,見Java反射詳解。

③插件資源訪問

res里的每一個資源都會在R.java里生成一個對應的Integer類型的id,APP啟動時會先把R.java註冊到當前的上下文環境,我們在代碼里以R文件的方式使用資源時正是通過使用這些id訪問res資源,然而插件的R.java並沒有註冊到當前的上下文環境,所以插件的res資源也就無法通過id使用了。

查看源碼,通過「addAssetPath」方法重新生成一個新的Resource對象來保存插件中的資源,避免衝突。

關於插件資源訪問,見使用插件中的R資源。

④代理模式

插件化實現的過程主要靠欺上瞞下,坑蒙拐騙來實現。想想雖然載入進來了Activity等組件,但也僅僅是最為一個對象而存在,並沒有在AndroidManifest中註冊,沒有生命周期的回調,並不能實現我們想要的效果。因此無論是dynamic_load_apk通過代理activity來操控插件activity的方式,還是DroidPlugin通過hook activity啟動過程來啟動插件activity的方式,都是對代理模式的應用。

關於代理模式,見靜態代理與動態代理。

至此,通過ClassLoader載入,然後通過代理模式讓Activity等組件具有生命周期實現真正的功能,並且解決了資源訪問問題。可能插件化已經可以簡單的實現一些初步的功能,然而插件化絕不止於此。更多的內容仍需要進一步探索,不過以上知識是基礎中的基礎,必備之必備。

三、Android插件化開源項目

介紹一下其中比較重要的兩個,實現思想不同,也是入門插件化可以學習的兩個。

Dynamic-load-apk

Dynamic-Load-Apk簡稱DL,這個開源框架作者是任玉剛,他的實現方式是,在宿主中埋一個代理Activity,更改ClassLoader後找到載入插件中的Activity,使用宿主中的Activity作為代理,回調給插件中Activity所以對應的生命周期。這個思路與AndroidDynamicLoader有點像,都是做一個代理,只不過Dynamic-load-apk載入的插件中的Activity。

項目地址:https://github.com/singwhatiwanna/dynamic-load-apk

DroidPlugin

DroidPlugin是張勇實現的一套插件化方案,它的原理是Hook客戶端一側的系統Api。

項目地址:https://github.com/DroidPluginTeam/DroidPlugin

既然著重介紹了兩個項目,必然要學起來,怎麼學習呢?

好在已經有前人把自己的學習經驗分享出來,那麼我們只需要結合源碼進行學習即可。

四、Dynamic-load-apk詳解

Android插件化學習之路(一)之動態載入綜述

Android插件化學習之路(二)之ClassLoader完全解析

Android插件化學習之路(三)之調用外部.dex文件中的代碼Android插件化學習之路(四)之使用插件中的R資源Android插件化學習之路(五)之代理ActivityAndroid插件化學習之路(六)之動態創建ActivityAndroid插件化學習之路(七)之DL插件開發該注意的坑Android插件化學習之路(八)之DynamicLoadApk 源碼解析(上) Android插件化學習之路(九)之DynamicLoadApk 源碼解析(下)

五、DroidPlugin詳解

Hook機制之動態代理

Hook機制之Binder HookHook機制之AMS&PMS

Activity生命周期管理

插件載入機制廣播的管理Service的插件化ContentProvider的插件化

六、總結

以上內容僅是Android插件化的入門知識,目前認知尚淺。

插件化、熱更新等技術在2016開始迅速發展,這即是業務發展的需求,也是我們需要緊跟前沿學習的技術。

自己是從事了七年開發的Android工程師,不少人私下問我,2019年Android進階該怎麼學,方法有沒有?

沒錯,年初我花了一個多月的時間整理出來的學習資料,希望能幫助那些想進階提升Android開發,卻又不知道怎麼進階學習的朋友。【包括高級UI、性能優化、架構師課程、NDK、Kotlin、混合式開發(ReactNative+Weex)、Flutter等架構技術資料】,希望能幫助到您面試前的複習且找到一個好的工作,也節省大家在網上搜索資料的時間來學習。

喜歡我的文章可以點贊+關注我的【個人主頁】獲取免費資料,後續我將繼續分享更多Android技術乾貨,感謝支持!

資料大全

推薦閱讀:

相关文章