1. 程式人生 > >Android外掛開發初探——基礎篇

Android外掛開發初探——基礎篇

Android外掛開發初探

對於Android的外掛化其實已經討論已久了,但是市面上還沒有非常靠譜成熟的外掛框架供我們使用。這裡我們就嘗試性的對比一下Java中,我們使用外掛化該是一個怎麼樣的流程,且我們如何將此流程移植到Android框架上去使用。很多程式碼都是內部資料,不喜勿噴,謝謝~

為什麼要外掛化?

  • 功能越來越多
  • 程式碼、安裝包越來越大
  • 小的更新也需要重新發布
  • 更新頻繁,安裝成本太大
  • 使用者無法選擇性載入需要的模組
  • ……

外掛化的好處

  • 主安裝包較小
  • 強制模組化,降低耦合度
  • 減少整體更新的次數
  • 外掛可單獨靜默更新
  • 使用者可以有所選擇
  • ……

外掛化的要求

  • 沒有獨立執行的入口
  • 主應用控制,下載、安裝、刪除、靜默升級、開啟和關閉
  • 主應用和外掛資源共享

安裝包的組成

enter image description here

需要安裝的外掛

對比一個安裝包的組成,我們要處理的東西也就是很多:

  • 主應用可以以Intent方式啟動具體的外掛,同時帶入Map型別引數或者json串引數
  • 使用相同的android:sharedUserId,資源資料共享
  • 根據sharedUserId來查詢外掛
  • queryIntentActivities查詢符合這個action的所有activity(或其它)即外掛
  • query方式可以獲得外掛的路徑以及實現介面類的類名
  • 通過檢索sharedUserId能夠得到路徑卻無法獲得到類名
  • 通常可以使用一個描述檔案(xml、json)描述外掛結構
  • createPackageContext()
  • getResourcesForApplication()

動態載入普通類
- Java 可以用 ClassLoader 動態載入.jar 中的Class檔案,android可以嗎?
- PathClassLoader
- DexClassLoader

介面類

    package com.plug;
    public interface InterfacePlug {
        public String function_01();
        public int function_02(int a,int
b); }

實現類

import com.plug.InterfacePlug;
    public class PlugImpl  implements InterfacePlug{
        @Override
        public String function_01() {
            return null;
        }

        @Override
        public int function_02(int a, int b) {
            return a+b;
        }
    }

主應用類

package com.host;

    public class MyhostActivity extends Activity {
        public void useDexClassLoader() {
            DexClassLoader cDexClassLoader =
                    new DexClassLoader("/mnt/sdcard/Myplugdex.jar", "/data/data/com.host", null, this.getClass()
                            .getClassLoader());
            try {
                Class<?> class1 = cDexClassLoader.loadClass("com.plug.PlugImpl");
                InterfacePlug interfacePlug = (InterfacePlug) class1.newInstance();
                int ret = interfacePlug.function_02(12, 13);
                tv.setText(" return value :" + ret);
            } catch (Exception e) {
            }
        }
    }

enter image description here

匯出外掛包時只能匯出實現類,否則會出現

Classref in pre-verified class resolvedtounexpected implementation
重複定義錯誤

當然,安裝包的解析與外掛安裝遠不止於類檔案的載入,我們還需要:

  • 不是普通類怎麼辦?
  • 系統元件如何接收回調?
  • 如何載入資源?
  • PackageInfo處理?
  • Resources的處理?
  • Assets的處理?

動態載入系統元件和資源

PluginLib
enter image description here

PluginHost
enter image description here

PluginTest

enter image description here

我們一個簡單的外掛框架就如下圖所示:
enter image description here

主應用列出安裝的Plugins,點選啟動對應的PluginActivity
enter image description here

當然,我們也可以根據此簡單的機制來完成一個完整的外掛系統。

  • 可以基本完整實現一個Activity

  • 可以繼續增加其他元件的外掛,完成更多的功能(Service,Receiver,ContentProvider,Application?)

此外掛機制的缺點

  • Manifest中註冊的資訊由系統控制,因此外掛需要許可權資訊需要預先註冊在主程式中。
  • 目前實現有一定的限制,如外掛宿主的相互呼叫、外掛間的相互呼叫

Github上的外掛框架,基於Fragment的開源外掛框架

/*
* @author zhoushengtao(周聖韜)
* @since 2015年1月27日 上午14:02:22
* @weixin stchou_zst
* @blog http://blog.csdn.net/yzzst
* @交流學習QQ群:341989536
* @私人QQ:445914891
/

enter image description here