Flutter 静态挂载腾讯X5WebView(Tbs)浏览器内核
文章目錄
- 背景
- 一、尋找Android WebView 內核替換方案(在native層面驗證)
- 1.CrossWalk
- 2.騰訊X5瀏覽器
- 1)動態集成
- 2)靜態集成
- 二、Flutter 靜態集成的X5WebView 的插件開發
- 1.StaticTBS Flutter Plugin(插件) 開發
- 1)創建Flutter Plugin
- 2)編寫Android Native代碼
- 3)編寫Flutter插件代碼
- 三、集成插件項目的編譯
- 1. 針對“Shrink”做的修改
- 2.so庫打包機制
- 總結
背景
項目中(Flutter項目)有一個需求是通過webview加載界面,來顯示實時視頻(webrtc),那么問題是,不同Android手機瀏覽器對于webrtc視頻解碼的支持性有差異導致部分手機無法正確顯示視頻,部分手機只有聲音沒有視頻。那么我決定通過端側來解決這個問題(我猜測修改web端代碼進行適配也能解決),由此引申出了這篇文章,留作參考記錄。涉及到的主要知識點如下:
一、尋找Android WebView 內核替換方案(在native層面驗證)
1.CrossWalk
經過測試,最新版本的CrossWalk并不能解決問題,仍然存在視頻無法解碼的問題。集成方式不再多說,相關教程很多。要注意的是crosswalk webview 想要略過ssl驗證,需要修改源碼中的SslUtil文件,修改為如下,直接忽略掉ssl異常。
public static boolean shouldDenyRequest(int error) {if (error >= -214 && error <= -200) {switch(error) {case -213:case -212:case -211:case -208:case -207:case -206:case -203:case -202:case -201:case -150:case -129:return false;default:return false;}} else {throw new AssertionError();}}然后將這個java文件編譯成".class"文件后,替換到crosswalk的aar包中。我在驗證過程中也做了一些工作,把用到的資源分享一下,以便有同學用得到,下面的下載鏈接是編譯成.class的SslUtil文件(其實這個是比較難搞的),將內核的aar sdk解壓替換即可,可以到crosswalk官網自行下載32or64位的sdk。
下載鏈接
提取碼:8cy5
2.騰訊X5瀏覽器
另外一個方案是騰訊的X5瀏覽器內核(https://x5.tencent.com/),經測試,可以解決我的問題,兼容性良好,有兩種集成方式說明一下
1)動態集成
動態集成具體方式官網上&其他帖子有很多說明,自行查找。經過測試,動態集成在Native項目中,內核掛載還算相對穩定(也有反復掛載不成功的情況),但是已Flutter 插件(Flutter 插件為靜態集成)的方式,集成到Flutter項目后,體驗非常之差,內核掛載成功率很低。所以動態集成方案pass,無法使用。(說句題外話,雖然這里只寫了一段,但是驗證過程確實還是用了一些時間的)
2)靜態集成
那么目前就明確了兩點,要解決兩個問題,首先是采用x5Webview替換內核方案,其次是需要靜態集成。
參考文章 原生項目需要靜態集成的同學對照這篇文章集成即可。
我這里補充一下我提取到到的64位內核資源(實際提取不難但我覺得麻煩,其實用32位的so文件足夠),下載鏈接如下:
下載鏈接
提取碼:fmy5
到此,這兩個問題圓滿解決。
二、Flutter 靜態集成的X5WebView 的插件開發
明確了方案,并且tbs靜態集成也ok,那么下一步就是要創建一個靜態集成的X5WebView的Flutter插件給Flutter項目使用,搜索了一下目前只有x5webview動態集成的flutter插件,那么這里就需要自己去搞一個插件來用,這里我借鑒了pub上已有的動態繼承tbs的庫。
插件提供了兩種使用方式,一種是直接從Flutter界面跳轉到Native方式使用了Tbs瀏覽器的Activity,一種是直接使用實現了TbsWebView的Flutter Widget
1.StaticTBS Flutter Plugin(插件) 開發
1)創建Flutter Plugin
as中,點擊File->New->New Flutter Project ,彈出選擇項目類型界面,選擇Flutter Plugin,點擊Next,之后填寫相應信息,最后finish,完成創建。創建的項目中內含一個example目錄(是一個flutter 項目),這個是用來調試plugin功能的,可作為臨時宿主使用。
2)編寫Android Native代碼
這點比較關鍵的,我想通過android studio 開發原生部分的代碼,關鍵點是,先要構建一下生成的eample項目,cd 到 example目錄,執行“flutter build apk ”即可,構建完成(是否成功不重要),之后就可以通過android studio 打開項目進行native開發,要注意的是,要打開example里面的android項目。
將提取到的armeabi架構的tbs so庫文件以及,靜態加載用到的jar包導入項目。
3)編寫Flutter插件代碼
這里涉及到的代碼以及知識點較多,主要是插件開發相關,后面我也許會單獨寫文章記錄,就不在這單獨講解了,可以搜索Flutter Plugin插件開發相關文章,目前項目已上傳到git,請自行查看
插件項目地址
三、集成插件項目的編譯
使用靜態tbs插件后,直接打包還是會發現內核掛載失敗,核心問題就是我目前還沒有提取到不同架構下的tbs so庫,只提取到了armeabi架構的,受限于tbs掛載規則或者是flutter so加載機制,tbs的armeabi so庫并不能向上兼容,放在armeabi-v7下不不好用。只能放到armeabi文件加下才可以保證加載成功,所以還需要關注一下下面的說明
1. 針對“Shrink”做的修改
當項目集成了靜態內核,會發現還是無法掛載,是因為flutter的打包apk機制 ,進行了“shrink”操作,將“com.tencent.cmtt” 包下的“utils”文件夾給“優化”掉了,誤傷友軍,所以為了能正常掛載靜態內核,那么需要對flutter gradle文件進行修改。
Flutter 本身gradle的文件路徑 : D:\你的flutter本地源碼文件夾\flutter_windows_v1.9.1+hotfix.6-stable\flutter\packages\flutter_tools\gradle打開這個路徑下的“flutter.gradle” 文件進行修改,修改這個部分代碼,將注釋部分屏蔽掉,這樣flutter工程在打包anroid項目的時候,就不會去shrink,對apk進行瘦身了,這里要注意,如果修改了flutter源碼下的代碼,后面想要通過“flutter upgrade”升級版本的時候會出錯,需要先revert掉,才可以正常升級。
private static Boolean shouldShrinkResources(Project project) {//將這個函數屏蔽掉if (project.hasProperty("shrink")) {return project.property("shrink").toBoolean()}return false}2.so庫打包機制
接下來要講一下到Flutter so 庫打包機制了,這里會延伸出一個flutter常見問題“couldn’t find “libflutter.so””,特別是你通過命令行進行打包的時候更容易出現這個問題,原因稍后講解。
當解壓正常的Flutter apk包,我們可以看到lib下的armeabi,arm64-v8a,x86等文件夾下會有“libflutter.so”以及“libapp.so”這兩個文件,可以這樣理解,libapp.so他就是我們用flutter寫的業務邏輯所打包的產物,libflutter.so實際上可以理解為libapp.so執行所必備的環境之一,正常運行的時候根據手機架構加載對應的so庫,達到native層面優化的效果。
那么回到上面的問題上來,“couldn’t find "libflutter.so”導致崩潰,極大概率就是你使用了一些plugin,或者是引用了一些第三方庫文件,打包時導致slibflutter.so庫沒有被打到指定的文件夾下,導致應用崩潰,如果是libapp.so沒有被打進去,應用只是會白屏,因為找不到UI以及邏輯代碼。
解決這個問題需要你理一下你項目中用到了哪些第三方so庫,特別關注plugin,然后可以通過修改android目錄下的ndk打包模式來進行調整。
修改的位置如下圖:
有兩種情況
如果你只打算適配arm架構,那么就修改為只打包armeabi-v7即可,你需要保證所有的so庫,都有這個架構的so文件。
這里有一個坑,flutter現在打包默認不支持將libflutter.so以及libapp.so打到armeabi下,如果你想向上兼容,只對armeabi做適配那是行不通,這里有個騷操作,那就是先生成armeabi-v7 的apk,解壓后拿到這兩個so庫,手動復制到armeabi目錄下,在進行只有armeabi架構的打包,就可以了,是有些麻煩,注意,目前如果使用這個插件,需要按照這個步驟操作。
其實也可以修改flutter gradle文件,讓它可以將這兩個so文件打包到armeabi目錄下,不是很好搞。
如果你打算適配不同架構,核心就是要不把不同架構so庫找全了,全部統一到對應so目錄下,在進行打包。
如果還是有問題,有個排查技巧,拿到啟動會崩潰的apk,丟到as里面,查看lib文件,可以看到哪些so文件出了問題,這樣比較直觀
上圖所示,armeabi有41MB,是因為我把tbs瀏覽器內核放到了armeabi文件夾下,打包的是全平臺,所以其他三個下面沒有這些so文件,所以如果運行在arm64,x86設備上,內核是會掛載失敗的。
總結
總結一下心得:
首先這邊博客還只是算是給出了解決思路,實際看起來有些雜亂,雜亂的原因是目前我這個方案肯定不是最優解,需要后續完善,這里做一下記錄,如果能吸引到牛人來一起探討那更好了,我下一步的思路就是繼續嘗試修改flutter gradle,讓flutter支持打包armeabi架構的apk,因為時間不是很多,之前只是簡單試過沒有成功。如果哪位有思路歡迎交流。
近期的一些思考
對于技術,每一個點,往細了深究都會牽扯到好多東西,需要靜下心來去研究,試錯,盡可能的使點連成片。以這篇文章來講,我還有好多地方做的不過好,需要后續改進。
對于項目,不同業務情況不同的分析方式,面對不同Bug也要有不同的解決思路,具體問題具體分析,不要局限于一小塊,已萬變應對不變。
總結
以上是生活随笔為你收集整理的Flutter 静态挂载腾讯X5WebView(Tbs)浏览器内核的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux基础命令(一)
- 下一篇: html里面判断字段显示,HTML特殊字