Shadow支持WebView使用file:///android_asset/協議加載插件資源的方法

在正常的App開發中,咱們能夠用這樣的代碼加載App的Assets中打包的Web頁面。html

webview.loadUrl("file:///android_asset/index.html");
複製代碼

Android系統實現這個功能時,並無像咱們想象的使用webview對象的Context去查找Assets資源。而是經過當前應用的ApplicationId,反查了當前安裝的應用的apk路徑。因此查到的天然是安裝的宿主應用。在宿主的apk中天然是找不到插件的Assets的。關於這個設計的緣由,我猜想大概是由於WebView的渲染是在一個單獨的進程中的,因此不方便拿到當前webview對象的context。android

做爲插件框架,咱們的目標始終是儘量的讓本來正常安裝能運行的代碼,在插件環境下也能運行。而這個API在業務開發中還比較經常使用,所以這個API的支持就比較重要了。web

雖然我沒有作過特別普遍的調研,但我確實沒見過其餘插件框架支持這個能力。因此我直接講一下Shadow是怎麼在不使用非公開API的前提下支持這個功能的。bash

我受到了「Web離線包」方案的啓發。在「Web離線包」方案中,客戶端能夠在本地攔截http請求,而後以本地資源直接返回。經過將一些Web資源直接打包在客戶端中,經過這種技術能夠提升Web的加載速度。所以,咱們就能夠應用AOP思想,對WebView loadUrl中file:///android_asset/協議進行修改。框架

因此方案很是簡單,先經過Shadow Transform將App中用到的WebView都換成ShadowWebView。再Override ShadowWebView的loadUrl方法。將請求來的file:///android_asset/協議都修改爲http://android.asset/協議。而後就能夠採用「Web離線包」的方法,從插件的Assets中拿出須要的資源返回給這個請求了。之因此要將file協議換成http協議,是由於這種攔截本地請求的能力只支持http協議。ide

關於這部分代碼,請查看com.tencent.shadow.core.runtime.ShadowWebView類的實現。spa

PS:我剛剛Google的時候發現還有一個咱們沒用過的file:///android_res協議,有興趣的同窗能夠幫忙實現一下,參與到Shadow的開源共建中來。插件

相關文章
相關標籤/搜索