2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

男坂Advent Calendar 2020

Day 8

[Flutter][Add-to-app] デバッグビルドしたapk内のlibflutter.soが壊れる問題と回避方法

Posted at

問題

Kotlinで実装されている既存アプリにFlutterを追加した所、デバッグビルドしたapkを端末にインストールできないことが起きるようになった。頻度は10回に1回くらい。

エラー発生時のlogcatの抜粋
2020-12-01 16:09:54.960 1578-2005/? W/ziparchive: Zip: inflate zerr=-3 (nIn=0xb40000787007ebda aIn=25638 nOut=0xb40000787006ebc0 aOut=24608)
2020-12-01 16:09:54.960 1578-2005/? W/zipro: ExtractToMemory failed with Zlib error
2020-12-01 16:09:54.960 1578-2005/? E/NativeLibraryHelper: Failed uncompressing libflutter.so to /data/app/vmdl854882831.tmp/lib/arm64/tmp.hVakYp
...
    --------- beginning of system
2020-12-01 16:09:54.961 1578-2005/? W/NativeHelper: Failure copying native libraries [errorCode=-18]

原因

apkのビルド時にlibflutter.soを圧縮しているが、それが正常できないのが原因。
問題が起きる時のapkからlibflutter.soを取り出してみると、サイズが約200KBになっている。libflutter.soは、正常時なら10MB以上ある。

回避策

libflutter.soの圧縮に問題があるので、libflutter.soの圧縮をしないことで問題は回避できる模様。
AndroidManifestのextractNativeLibsにfalseを設定することで、実現できる1

<manifest>
    <application
        android:extractNativeLibs="false" >
        ...
    </application>
</manifest>

ただし、libflutter.soを圧縮しなくなる分、アプリのサイズは増大するので注意。
問題が起きていたアプリでは、サイズが120MBから230MBに増えた。
基本、Wifi環境下でしかダウンロードしないのでよいが、そうでないなら、別の対処を考えた方が良い。
同じアプリでも、aabをReleaseビルドする場合は問題が起きたことがない。なので、デバッグビルド固有の設定に問題がありそうである。

補足

原因詳細

エラーログの「Zip: inflate zerr=-3」の部分に着目。エラーコードの定義箇所を見ると、 kInvalidFileというエラーで、意味は「入力ファイルを zip アーカイブとして処理できません。通常、小さすぎたり、大きすぎたり、有効な署名がないために処理できません」。

ということでlibflutter.soが破損しているということが分かる。

問題が起きるとき、MacのFinderからそのapkファイルを解凍しようとするとエラーが起きるので、Android OSの解凍処理には問題ないことが分かる。shellのunzipコマンドならapkファイルの解凍できる。解凍後、libflutter.soのサイズを見ると、約200KBになっていることが分かる。

Firebase Test Labでのエラーの見え方

この問題に気づいたのは、CIでFlutte入りのアプリをデバッグビルドし、Firebase Test LabでE2Eテストを実行しようとしたとき。
「The app APK is not a valid Android application.」というエラーが表示される。
以下、エラーログを示す[^2]。

sudo gcloud firebase test android run \
  --app "${DEBUG_APP_APK_PATH}" \
  --test "${TEST_APK_PATH}" \
  --test-targets "user bot2" \
  --device model=NexusLowRes,version=28 \
  --use-orchestrator \
  --environment-variables clearPackageData=true,coverage=true,coverageFile="/sdcard/coverage.ec" \
  --directories-to-pull /sdcard \
  --results-bucket ${TEST_RESULTS_BUCKET}

Have questions, feedback, or issues? Get support by visiting:
  https://firebase.google.com/support/

Uploading [app/build/outputs/apk/*******/debug/app-*******-debug.apk] to Firebase Test Lab...
Uploading [app/build/outputs/apk/androidTest/*******/debug/app-*******-debug-androidTest.apk] to Firebase Test Lab...
Raw results will be stored in your GCS bucket at [https://console.*******ers.google.com/storage/browser/*****************************/2020-12-01_04:15:54.367295_CwcV/]

Test [matrix-2dcbutvhf7ld6] has been created in the Google Cloud.
Firebase Test Lab will execute your instrumentation test on 1 device(s).
ERROR: (gcloud.firebase.test.android.run) 
Matrix [matrix-2dcbutvhf7ld6] failed during validation: The app APK is not a valid Android application.

Exited with code exit status 1
CircleCI received exit code 1
  1. 英語のリファレンスを読むと、Android Gradle Plugin 3.6.0以上だとデフォルトfalseとのこと。ただ、問題のアプリはextractNativeLibsの設定に対応していないAndroid 4.4が最小サポートOSのせいか、trueの動作になっていた。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?