18
5

More than 5 years have passed since last update.

FlutterでAndroidネイティブライブラリを取り込む時の注意点

Last updated at Posted at 2018-12-20

はじめに

FlutterでAndroid開発中に特定のライブラリを導入すると、ビルドは通るのにアプリ起動時にこんなエラーで強制終了することがあるかもしれません。

couldn't find "libflutter.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:1011)
        at java.lang.System.loadLibrary(System.java:1657)

要はFlutterのライブラリが見つからない、ということですが、これはFlutterに限らずですが、JNIを使ったライブラリを取り込むときに注意する点です。

原因

Flutterはネイティブライブラリであるsoファイルとしてアプリ上で動作します。その際、別のライブラリでもネイティブライブラリを使っていた場合、必要なsoファイルがapk内に取り込まれずに強制終了しています。
順を追って説明していきます。

Flutterから生成されるsoファイル

まず他のライブラリを入れる前の状態でアプリをビルドしてapkの中身を見ると以下のようになっています。
スクリーンショット 2018-12-19 14.32.02.png
このように3つのディレクトリにそれぞれlibflutter.soが配置されています。

2019/1/17 修正:
flutterの現時点の最新1.1.9では、armeabi-v7aのサポートが終了し、arm64-v8aへ以降したため、記述を変更しました。キャプチャは古いままですのでご注意ください。(すみません、詳細確認中です)

  • arm64-v8a
  • x86
  • x86_64

それぞれの詳細については公式参照:ABI管理

他のライブラリを入れた場合

私の場合、Google VR SDKを導入したため発生しました。
Google VR SDKの場合、下記の3つが用意されていました。

  • arm64-v8a
  • armeabi-v7a
  • x86

参考:https://github.com/googlevr/gvr-android-sdk/blob/master/samples/ndk-hellovr/build.gradle#L47
その結果、lib配下には4つのディレクトリが生成され、それぞれの構成は以下のようになりました

  • arm64-v8a
    • Flutter(libflutter.so)
    • Google VR(libgvr.so, liboanorenderer.so)
  • armebi-v7a
    • Google VR(libgvr.so, liboanorenderer.so)のみ
  • x86
    • Flutter(libflutter.so)
    • Google VR(libgvr.so, liboanorenderer.so)
  • x86_64
    • Flutter(libflutter.so)のみ

スクリーンショット 2018-12-19 14.37.03.png
スクリーンショット 2018-12-19 14.37.18.png
スクリーンショット 2018-12-19 14.37.31.png

何が起こるのか?

lib配下のsoファイルは、端末のハードによってどのディレクトリが使用されるか決まります。今回の場合、armebi-v7aとx86であれば両方のsoファイルが格納されているため、問題なく起動できます。
一方、arm64-v8aやx86_64を使用する端末で起動した場合どうなるでしょう?ディレクトリ内に必要なsoファイルが揃っていないため、loadLibrary時にcouldn't findと言われてしまうわけです。

どうすれば良いのか?

結論からいうと、gradleでabiFilterを指定する必要があります。

build.gradle
android {
  ...
  defaultConfig {
    ...
    ndk {
      // Specifies the ABI configurations of your native libraries Gradle should build and package with your APK.
      abiFilters "x86", "arm64-v8a"
    }
  }
  ...
}

今回の場合、Google VRとFlutter両方が用意されているのは、x86とarmebi-v7aの二つのみなので、その二つをabiFiltersで指定します。
これにより、apkに取り込まれるsoファイルはabiFiltersで指定されたx86とarmebi-v7aのみとなり、それ以外のx86_64およびarm64-v8aはディレクトリが生成されなくなります。

まとめ

Flutterもネイティブライブラリを使用していることを忘れずに、soファイルが見つからないと強制終了した場合はabiFilterの見直しを検討してみてください。
また、クラッシュは端末のハードに依存するため、Play Consoleのリリース前レポートを利用して確認しておくのがよいかと思います。

18
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
5