Activity的外掛程式化 三

2021-09-24 06:25:12 字數 3556 閱讀 4505

上面一篇文章已經實現了intent解析和targetclass的還原工作,這篇文章會來說說:

1. 外掛程式apk的解析

#### 2. classloader的問題

3. 資源的問題

1.外掛程式apk的解析

說到這個我們很容易想到一般的apk的安裝過程也是需要解析apk的資訊的,下面貼一篇比較好的文章。 android apk安裝過程分析

取自上面的部落格,apk的安裝過程與pms有很大的關係,很多操作都是由pms完成的,有興趣的可以去了解。

private void installpackageli(installargs args, packageinstalledinfo res)  catch (packageparserexception e) 

}複製**

解析apk檔案呼叫了packageparserparsepackage方法。 現在一般的外掛程式話框架也是這樣做的,解析apk也是通過呼叫這個方法,當然除了這個,還有一些開源的解析apk的框架例如:apk-parser

這裡要說明的是packageparser這個類在不同的安卓sdk版本裡面有不少的改動,所以需要做相容。 這裡比較一下滴滴的virtualapk和droidplugin的做法,他們的做法基本一樣,比較不同的是virtualapk框架把安卓framework把安卓裡面外掛程式化需要的類提取出來了,作為乙個lib,外掛程式化框架virtualapk provide的形式依賴這個庫,就可以直接呼叫裡面的方法,有效避免了反射帶來的效能方面的損失。

droidplugin裡面的相容,下圖是virtualapk裡面的做法,抽出framework裡面的類,做成乙個庫,外掛程式化框架provide形式依賴。

public final class packageparsercompat 

* @throws packageparser.packageparserexception

*/public static final packageparser.package parsepackage(final context context, final file apk, final int flags)

throws packageparser.packageparserexception else

if (build.version.sdk_int >= 21) else

}/**

* 7.0及以後的相容處理

*/private static final class packageparserv24 , pkg, flags);

return pkg;}}

/*** 5.0,5.1,6.0的處理

*/private static final class packageparserlollipop catch (throwable e)

return pkg;}}

/*** 低版本的處理

*/private static final class packageparserlegacy , pkg, flags);

return pkg;}}

}複製**

**處理,對了,我最近在給virtualapk框架新增注釋,**在這裡:virtualapk

2. classloader的問題

classloader問題之前已經提過了,外掛程式是不是能使用宿主的類,如果要能使用的話,外掛程式是需要繼承宿主的classloader的,宿主是不是能載入到外掛程式的類,如果能,外掛程式的dex是要放到宿主的dex陣列裡面滴。 virtualapk在處理這個問題的時候分了兩種情況,一種是宿主有價值外掛程式類的能力,一種是沒有,實現方式那是相當的簡單。(ps:外掛程式是一直可以載入到宿主類的)

/**

* 建立外掛程式classloader

** @param context host的classloader

* @param apk 外掛程式檔案位置

* @param parent host的classloader

* @return 外掛程式classloader

*/private static classloader createclassloader(context context, file apk, file libsdir, classloader parent) catch (exception e)

}return loader;

}複製**

這裡的處理,就很簡單了,如果宿主有載入外掛程式類的能力,那麼,把外掛程式的dex檔案放到宿主的dex列表裡面(至於為什麼要這樣做,可以了解一下安卓的basedexclassloader)。

3. 資源的問題

關於資源的問題和**的問題差不多,如果想要共享資源,那麼需要把外掛程式的資源新增到宿主的資源裡面,當然也可以外掛程式就自己管理自己的資源,每個外掛程式乙個資源管理器。

這裡需要注意的是如果把外掛程式的資源放到宿州的資源裡面那麼需要解決乙個問題,檔案描述的明白點就是,宿主是乙個正常的apk檔案,資源id是0x7f開頭,外掛程式也是apk檔案,資源id也是0x7f開頭,那麼這樣的話,外掛程式和宿主的資源id不是就存在重複的可能了麼,答案是肯定的,這種可能很大呢,為了解決這個問題也有兩種解決方案:(這裡只討論修改aapt的方法) 1.修改aapt,讓外掛程式資源id不再以0x7f開頭 2.使用gradle plugin外掛程式修改資源產物.ap_裡面的資源id,然後重新壓縮回去

virtualapk在處理這個問題上也是分兩種情況,一種是把外掛程式的資源新增到宿州的資源裡面,一種是外掛程式自己管理自己的資源,當然實現的**依舊非常簡單。

/**

* 建立外掛程式的assetmanager

** @param context 宿主context

* @param apk 外掛程式apk檔案

* @return 外掛程式assetmanager

*/private static assetmanager createassetmanager(context context, file apk) catch (exception e)

}/**

* 建立外掛程式的資源管理器

** @param context 宿主host

* @param apk 外掛程式apk檔案

* @return 外掛程式resources

*/@workerthread

private static resources createresources(context context, file apk) else

}複製**

這裡就分兩種情況,如果資源要合併的話,就把外掛程式資源放入宿主裡面,不然外掛程式就使用自己的資源。

外掛程式的後台也要考慮到這些問題。 外掛程式的載入,外掛程式載入是需要釋放dex優化dex檔案的,那麼這個過程的管理公升級的一些問題。

5. 後續

其實這個系統的外掛程式化基本都是基於virtualapk講解的,個人更喜歡360團隊的外掛程式化框架replugin,等這系列結束之後會去研究他。 個人打算寫乙個外掛程式化的後台pluginserver,這個後台是為replugin服務的,當然,也會考慮到我上面說的一些問題,版本的問題,爭取做乙個通用的外掛程式化平台的後台。

8個類搞定外掛程式化 Activity實現方案

前兩篇文章寫完後,有人跟我說怎麼覺得你文章風格突然變了,最近講了這麼多內容變囉嗦了,沒有你高效率精簡的風格了。寶寶心裡苦啊,不是我不想,實在是外掛程式化這東西,如果你不知道理論知識的話,根本沒辦法去理解啊。接下來這幾篇我盡可能的以實踐為主,讓大家都能看得懂。在 序文 android 外掛程式化的過去...

三方 9 外掛程式化

一 外掛程式化需解決的問題 1 外掛程式dex載入問題 通過反射拿到dexclassloader,解析外掛程式dex與宿主dex合併後,重新插入宿主dexpathlist中。2 外掛程式元件生命週期問題 提前佔坑註冊 元件,在校驗前儲存真實跳轉資訊,利用 元件通過系統校驗,校驗後攔截h跳轉,取出資訊...

App啟動(三)Activity的建立

private final boolean int pid catch exception e if normalmode catch exception e return true boolean throws remoteexception catch remoteexception e ret...