dynamic-load-apk-Apk動態加載框架使用初體驗

y9RUe3 8年前發布 | 9K 次閱讀 Android開發 移動開發

因為想要將本網站上的開源代碼直接做成一個能顯示效果的app,決定摸索下android的插件開發,發現只有兩個開源的插件系統可選:

AndroidDynamicLoader

dynamic-load-apk

因為第一個只允許在fragment的基礎上開發插件,第二個沒有此限制并且是國人開發,文檔比較齊全,所以選擇了第二個。

 

下載dynamic-load-apk

dynamic-load-apk 簡稱DL框架,從github上下載DL,如下:

lib是Library,sample是例子程序,打開sample如下:

根據官方的解釋,有三種模式,其中main目錄下才是其推薦的獨立插件模式,所以直接不管depend_on_interface這個文件夾了。

其中main-host是宿主,他需要引用DL的Library才能運行,main-plugin-a,以及main-plugin-b是插件。

 

運行sample中的宿主和插件

我將main直接import到eclispe中,并且將DL的Library也導入,將main-host添加Library依賴,運行main-host程序,當然了 顯示的是沒有插件,因為main-host程序需要在sdcard的根目錄下建立DynamicLoadHost目錄,然后DynamicLoadHost目錄中放入插件的apk。這主要是因為main-host程序的代碼是這樣寫的:

private void initData() {
    String pluginFolder = Environment.getExternalStorageDirectory() + "/DynamicLoadHost";
    File file = new File(pluginFolder);
    File[] plugins = file.listFiles();
    if (plugins == null || plugins.length == 0) {
        mNoPluginTextView.setVisibility(View.VISIBLE);
        return;
    }
    for (File plugin : plugins) {
        PluginItem item = new PluginItem();
        item.pluginPath = plugin.getAbsolutePath();
        item.packageInfo = DLUtils.getPackageInfo(this, item.pluginPath);
        if (item.packageInfo.activities != null && item.packageInfo.activities.length > 0) {
            item.launcherActivityName = item.packageInfo.activities[0].name;
        }
        mPluginItems.add(item);
        DLPluginManager.getInstance(this).loadApk(item.pluginPath);
    }
    mListView.setAdapter(mPluginAdapter);
    mListView.setOnItemClickListener(this);
    mPluginAdapter.notifyDataSetChanged();
}

pluginFolder指定為DynamicLoadHost。

當然你自己寫的宿主程序完全可以指定為其他目錄,甚至直接來源于網上(只是猜想),如果不支持直接加載遠程的apk,我們可以先從網上下載下來,放到我們程序指定的一個目錄。

接著我們再運行main-plugin-a,產生一個apk放到剛剛在sdcard建立的DynamicLoadHost目錄。

然后再次打開宿主程序,點擊這個插件,和預期是一致的,插件就像一個apk一樣執行了。

 

嘗試自己的apk

雖然官方文檔已經說明插件apk需要滿足一些要求(context不能用this,jar不能打包在apk中(主要是DL的jar以及surport的jar)等),但是我還是忍不住要嘗試一下直接把我的apk放進sdcard的DynamicLoadHost目錄,運行宿主程序,列表中能看到我的apk程序,點擊,沒反應。。。。。。。。。

雖然在意料之中,但是小心臟還是小小的失落。

先說下我運行的這個程序叫GossipView,在github上可以下載,因為GossipView非常簡單且具有代表性,沒有依賴其他庫(GossipView是直接在demo中一起的),有activity,有一個自定義的GossipView。對于我準備開發的東西來說,如果這個東西都不能運行,那就沒什么意義了。

我開始改造我的GossipView,讓他可以作為插件了:增加了external-jars 將DL的jar放進去,并且將surport的jar也放進去,同時在.classpath中追加如下兩句:

<classpathentry kind="lib" path="external-jars/dl-lib.jar"/>
<classpathentry kind="lib" path="external-jars/android-support-v4.jar"/>

這樣,編譯的時候就能夠正常進行,但是打包的時候,就不會把上面兩個jar包打入到插件apk中。

 

接下來不是要改this為that嗎,改唄,我發現我的activity中只有一處用了this,替換成that,運行。得到了一個apk,但是很奇怪的是我的插件居然能直接運行,不是說那樣做兩個jar不會被打包進去嗎怎么還能運行了呢。。。。

管他的哦,先將這次的apk放進去再說。

運行宿主,點開我的插件,報錯了:

 

看來還真的是包多了,也就是說我的插件apk中其實把DL和surport的jar打包進去了。

 

我找啊找啊找,發現是自己粗心了,我在插件項目中添加了兩次DL,一次是用jar,一次是直接添加了Library的依賴。fuck。

好吧改過來之后,完全可以了,只是原本我應用的白色背景變成了黑色背景。

 

 本文由用戶 y9RUe3 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!