1. 程式人生 > >Android 系統上實現APK外掛機制——360手機助手

Android 系統上實現APK外掛機制——360手機助手

Droid Plugin

DroidPlugin 是360手機助手在Android系統上實現了一種新的外掛機制:它可以在無需安裝、修改的情況下執行APK檔案,此機制對改進大型APP的架構,實現多團隊協作開發具有一定的好處。

定義:

HOST程式:外掛的宿主。

外掛:免安裝執行的APK

限制和缺陷:

  1. 無法在外掛中傳送具有自定義資源的Notification,例如: a. 帶自定義RemoteLayout的Notification b. 圖示通過R.drawable.XXX指定的通知(外掛系統會自動將其轉化為Bitmap)
  2. 無法在外掛中註冊一些具有特殊Intent Filter的Service
    ActivityBroadcastReceiverContentProvider等元件以供Android系統、已經安裝的其他APP呼叫。
  3. Activity的LaunchMode支援不夠好,Activity Stack管理存在一定缺陷。Activity的onNewIntent函式可能不會被觸發。 (此為BUG,未來會修復)
  4. 缺乏對Native層的Hook,對某些帶native程式碼的apk支援不好,可能無法執行。比如一部分遊戲無法當作外掛執行。

特點:

  1. 支援Androd 2.3以上系統
  2. 外掛APK完全不需做任何修改,可以獨立安裝執行、也可以做外掛執行。要以外掛模式執行某個APK,你無需重新編譯、無需知道其原始碼。
  3. 外掛的四大元件完全不需要在Host程式中註冊,支援Service、Activity、BroadcastReceiver、ContentProvider四大元件
  4. 外掛之間、Host程式與外掛之間會互相認為對方已經"安裝"在系統上了。
  5. API低侵入性:極少的API。HOST程式只是需要一行程式碼即可整合Droid Plugin
  6. 超強隔離:外掛之間、外掛與Host之間完全的程式碼級別的隔離:不能互相呼叫對方的程式碼。通訊只能使用Android系統級別的通訊方法。
  7. 支援所有系統API
  8. 資源完全隔離:外掛之間、與Host之間實現了資源完全隔離,不會出現資源竄用的情況。
  9. 實現了程序管理,外掛的空程序會被及時回收,佔用記憶體低。
  10. 外掛的靜態廣播會被當作動態處理,如果外掛沒有執行(即沒有外掛程序執行),其靜態廣播也永遠不回被觸發。

使用方法:

整合

在host中整合Droid Plugin專案非常簡單:

  1. 我們只是需要將Droid Plugin當作一個lib工程應用到主專案中,然後:

  2. AndroidManifest.xml中使用外掛的com.morgoo.droidplugin.PluginApplication

    <application android:name="com.morgoo.droidplugin.PluginApplication" 
                 android:label="@string/app_name"
                 android:icon="@drawable/ic_launcher" 
    
  3. 如果你使用自定義的Application,那麼你需要在自定義的Application classonCreateattachBaseContext方法中新增如下程式碼:

    @Override
    public void onCreate() {
        super.onCreate();
        //這裡必須在super.onCreate方法之後,順序不能變
        PluginHelper.getInstance().applicationOnCreate(getBaseContext());
    }
    
    @Override
    protected void attachBaseContext(Context base) {
        PluginHelper.getInstance().applicationAttachBaseContext(base);
    }
    
  4. 將外掛中Libraries\DroidPlugin\AndroidManifest.xml所有provider對應的authorities修改成自己的,預設為com.morgoo.droidplugin_stub_P00,如下:

    <provider
        android:name="com.morgoo.droidplugin.stub.ContentProviderStub$StubP00"
        android:authorities="com.morgoo.droidplugin_stub_P00"
        android:exported="false"
        android:label="@string/stub_name_povider" />
    

    可以修改為自己的包名,如: com.example.droidplugin_stub_P00 防止跟其它本外掛使用者衝突:

    <provider
        android:name="com.morgoo.droidplugin.stub.ContentProviderStub$StubP00"
        android:authorities="com.example.droidplugin_stub_P00"
        android:exported="false"
        android:label="@string/stub_name_povider" />
    
  5. 整合完成。

安裝、解除安裝外掛:

  1. 安裝、更新外掛,使用如下方法:

    int PluginManager.getInstance().installPackage(String filepath, int flags)
    

    說明:安裝外掛到外掛系統中,filepath為外掛apk路徑,flags可以設定為0,如果要更新外掛,則設定為PackageManagerCompat.INSTALL_REPLACE_EXISTING返回值及其含義請參見PackageManagerCompat類中的相關欄位。

  2. 解除安裝外掛,使用如下方法:

    int PluginManager.getInstance().deletePackage(String packageName,int flags);
    

    說明:從外掛系統中解除安裝某個外掛,packageName傳外掛包名即可,flags傳0。

  3. 啟動外掛:啟動外掛的ActivityService等都和你啟動一個以及安裝在系統中的app一樣,使用系統提供的相關API即可。元件間通訊也是如此。