關於flutter android so庫相容性問題
so庫說明
so庫在android中,是使用c/c++程式碼編譯出來的庫檔案,可以使用ndk呼叫,就是你在android程式碼中見到的native方法,具體的實現就在so庫中
關於so庫相容性問題
andorid中或多或少都會引用到第三方庫,而很多第三方庫中都有so的存在,不論是複製到專案中(如百度地圖),或是gradle依賴(如個推)
其中都涉及到了so庫的相關問題,如果你選擇的庫是有所有cpu型別可選還好,如果不是,那麼就需要自定義設定了
舉個栗子
你的app依賴兩個庫,分別是lib1,lib2
lib1: arm64-v8a,armeabi-v7a lib2: armeabi-v7a
那麼當你執行在v7的手機上時,因為你的專案含有v7的so庫,所以沒有問題,可以跑起來
如果,你執行在v8手機上,那麼你的專案就會boom,崩了, 為啥呢? 這就涉及到so對齊了
so對齊
簡單來說,就是要有就必須都有,如果一個沒有,那就一個都不要
比如上面的例子,如果你是自己複製到專案下的,你需要刪掉arm64-v8a的資料夾
如果是個推那種使用gradle依賴的方案,那麼你需要修改gradle檔案,這個是我的個推的配置gradle
// 個推的ndk配置 apply plugin: 'com.android.application' android { defaultConfig { ndk { abiFilters "armeabi-v7a" // abiFilters "armeabi-v7a","arm64-v8a" } } buildTypes { debug { ndk { abiFilters "armeabi-v7a", "x86" // abiFilters "armeabi-v7a", "x86"/*, "arm64-v8a"*/ } } release{ ndk{ abiFilters "armeabi-v7a" } } } } repositories { maven { url "http://mvn.gt.igexin.com/nexus/content/repositories/releases/" } }
這裡因為涉及到flutter的除錯,而很多模擬器都是x86的,所以debug的情況下開啟了x86
最優選擇
原則上來講,so庫的最優選擇是提供所有的so,或者分cpu型別打包,這樣能做到最優,因為v8讀取v7的so庫會有效能上的損失
如果全打包到apk裡,則會增加apk體積
無奈,目前還沒有提供多cpu分apk上傳的應用商店,然後根據手機的cpu型別提供對應的下載
所以目前的方案是提供最低的cpu型別, 因為v7會去自動相容armeabi的 而v8會相容v7和armeabi
比如只提供armeabi so的,你可以相容3種cpu的手機,而只提供v7的就要少一點
目前android普遍應該都是v7+的了,而flutter提供的so也只有v7和v8兩種而已,所以我們基於這種情況,建議打包的時候自主刪除除armeabi-v7a以外的選項
使用如上的gradle能解決大部分問題,可以在gradle中再修改下打包指令碼,自動去除lib中的其他cpu型別
這部分可以參考美團的 flutter原理與實踐 SO庫相容性部分 來嘗試修改自己的gradle打包指令碼