1. 程式人生 > >關於flutter android so庫相容性問題

關於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打包指令碼