Flutter: 解决运行时错误 java.lang.UnsatisfiedLinkError...couldn't find "libflutter.so"

5,771 阅读2分钟

转载请标明出处: juejin.cn/post/684490…
本文出自: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中包含的元素