Flutter: 解決執行時錯誤 java.lang.UnsatisfiedLinkError...couldn't find "libflutter.so"

Wos發表於2018-12-25

轉載請標明出處: juejin.im/post/5c2260…
本文出自:Wos的主頁

我遇到的問題如下:

--------- beginning of crash
12-26 00:57:13.716 26266-26266/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.wos.mydemo, PID: 26266
    java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.wos.mydemo-1/base.apk"],nativeLibraryDirectories=[/data/app/com.wos.mydemo-1/lib/arm64, /data/app/com.wos.mydemo-1/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]] couldn't find "libflutter.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:984)
        at java.lang.System.loadLibrary(System.java:1554)
        at io.flutter.view.FlutterMain.startInitialization(FlutterMain.java:157)
        at io.flutter.view.FlutterMain.startInitialization(FlutterMain.java:134)
        at io.flutter.app.FlutterApplication.onCreate(FlutterApplication.java:22)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1025)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5658)
        at android.app.ActivityThread.-wrap2(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1731)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:159)
        at android.app.ActivityThread.main(ActivityThread.java:6385)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1096)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:883)
複製程式碼

解決:

  1. 開啟你的 android 工程的主 module(預設是app) 下的 build.gradle
  2. 修改 abiFilters 欄位, 只指定單一架構. 針對手機的應用推薦使用 "armeabi-v7a"; 針對平板的應用推薦使用x86

如下:

android {
    ...
    buildTypes {
        debug {
            ...
            ndk { abiFilters "armeabi-v7a" }
        }
    }
    ...
}
複製程式碼

其它:

這裡還是需要先普及一下關於android載入so包的小知識.

android會優先採用貼近手機架構的so包進行載入, 並且只載入相同架構的so包.

舉例來說, 如果你的應用有兩個帶so包的依賴庫, 其中一個庫帶有"arm64-v8a"和"armeabi-v7a"的so包, 而另一個只有 "armeabi-v7a"的so包, 那麼當你的手機(CPU)是"arm64-v8a"架構時就會發生這個問題, 而如果你的手機是"armeabi-v7a"的就沒有問題.

說會Flutter

出於包體積的考量, Flutter在打包時只針對特定版本的架構將libflutter.so包打進apk.

通過GooglePlay發行應用, 開發者可以為不同的架構的手機上傳包含不同so包的apk.這樣既可以兼顧更多的架構, 又能節省使用者的網路開銷.

但國內應用市場暫時還沒有這麼好的環境, 只能在一個apk中包含多個so包.

貌似目前還不能打所有版本的libflutter.so到一個apk中, 這個問題我會保持關注. 如果大家發現了真正的解決辦法, 請告訴我, 謝謝

參考:

Build APK for multiple target platforms

我試驗了幾種 abiFilters 的組合方式產生的不同結果

如果選擇 abiFilters "armeabi-v7a", "x86", 打出來的就只包含"x86"的libflutter.so包

如果是 x86, v7 ,v8 , 打出來的就是 x86的so包和, v8的so包 如果選擇 abiFilters "armeabi-v7a", "arm64-v8a", "x86", 打出來的就是包含"x86"和"arm64-v8a"的libflutter.so包

大家可以通過 AndroidStudio 自帶的工具 build -> Analyze Apk 檢視指定apk中包含的元素

相關文章