Flutterアプリを Android15 / 16kb page size 環境で動かしたらどうなるのか
Android15端末から、16kb page size環境といわれる、OSが管理するメモリの単位サイズが従来の4kbより大きくなる端末が出ます。
Flutterアプリの場合、どのような影響があるのでしょうか。
16kb page sizeの概要
Android15から、OSのメモリ管理の単位(ページサイズ)が4kbだったのが、16kbに切り替えられる。
それによりアプリの起動時間などのシステムパフォーマンスが向上する(らしい)。
アプリが影響を受けるのは、ネイティブコード(C/C++)を使用しているときです。apkを解凍したときに、共有ライブラリ(.so
)として出力されているものが影響を受けます。
Flutterの場合
Flutterはネイティブコードを使用しているので影響を受けそうですが、以下issueでは、次の理由により問題ないそうです。
-
libflutter.so
は16kb対応されてた - 16kb環境のエミュレータ (
Google APIs Experimental 16k Page Size ARM 64 v8a System Image
) で動かしても問題なかった
具体的に16kb対応しない場合にどのような影響があるのかというと、 試したところインストールすらできなくなりました。
実際に確かめてみましょう。
共有ライブラリ(.so)が16kb対応されているか確認
まずは、共有ライブラリ(.so)が16kb対応されてるか見ます。apkファイルを解凍すると、lib
フォルダがあるので、そちらに以下のスクリプト(上記リファレンスをご参考)を実行します。
alignment.sh
macで実行するので文字色を変更するコードを少し変更しています。
#!/bin/bash
# usage: alignment.sh path to search for *.so files
dir="$1"
RED="\033[0;31m"
GREEN="\033[0;32m"
ENDCOLOR="\033[0m"
matches="$(find $dir -name "*.so" -type f)"
IFS=$'\n'
for match in $matches; do
res="$(objdump -p ${match} | grep LOAD | awk '{ print $NF }' | head -1)"
if [[ $res =~ "2**14" ]] || [[ $res =~ "2**16" ]]; then
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
else
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
fi
done
lib/arm64-v8a/libflutter.so: ALIGNED (2**16)
lib/arm64-v8a/libnative-jpeg.so: UNALIGNED (2**12)
lib/arm64-v8a/libVkLayer_khronos_validation.so: ALIGNED (2**16)
lib/arm64-v8a/libpl_droidsonroids_gif.so: UNALIGNED (2**12)
lib/arm64-v8a/libimage_processing_util_jni.so: UNALIGNED (2**12)
たしかに libflutter.so
は大丈夫そうだけど、UNALIGNED
となっていて16kb未対応のものもありそうです...。と、とにかく、動かして見ましょう。
16kb環境で動くか
起動すらしない。
試した環境は以下
- Flutter 3.24.0
- AGP(Android Gradle Plugin): 7.3.0
- Android 15.0 エミュレータ(16 KB Page Size Google APIs)
エラーログは以下。
Launching lib/main.dart on sdk gphone16k arm64 in debug mode...
✓ Built build/app/outputs/flutter-apk/app-debug.apk
Error: ADB exited with exit code 1
Performing Streamed Install
adb: failed to install path/to/build/app/outputs/flutter-apk/app-debug.apk: Failure [INSTALL_FAILED_INVALID_APK: INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2]
Error launching application on sdk gphone16k arm64.
環境はAGP(Androidアプリをビルドするためのプラグイン)のバージョンが 7.3.0 ですが、
リファレンスによると 8.5.1 以上で何も変更なしでビルドOKとのことなので、当たり前の結果かと思いました...
念の為 zipalign
でapkファイルを確認。
~/Library/Android/sdk/build-tools/35.0.0/zipalign -c -P 16 -v 4 build/app/outputs/flutter-apk/app-debug.apk
...
191896672 resources.arsc (OK)
Verification FAILED
しっかり FAILED
とでてます。
そこで、リファレンスに記載の以下の対応を入れてリトライ。
android {
// ...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
...起動した!
~/Library/Android/sdk/build-tools/35.0.0/zipalign -c -P 16 -v 4 build/app/outputs/flutter-apk/app-debug.apk
...
43482514 lib/x86_64/libflutter.so (OK - compressed)
59375423 lib/x86_64/libimage_processing_util_jni.so (OK - compressed)
59397614 lib/x86_64/libnative-jpeg.so (OK - compressed)
59486515 lib/x86_64/libpl_droidsonroids_gif.so (OK - compressed)
Verification succesful
succesful
とあり、大丈夫そうです。
疑問
起動したapkに含まれる共有ライブラリ(.so)に対して、もう一度 alignment.sh
を実行してしてみたところ、結果は変わらず UNALIGNED
が含まれている理由がわかりませんでした... 🤔
lib/arm64-v8a/libflutter.so: ALIGNED (2**16)
lib/arm64-v8a/libnative-jpeg.so: UNALIGNED (2**12)
lib/arm64-v8a/libVkLayer_khronos_validation.so: ALIGNED (2**16)
lib/arm64-v8a/libpl_droidsonroids_gif.so: UNALIGNED (2**12)
lib/arm64-v8a/libimage_processing_util_jni.so: UNALIGNED (2**12)
Discussion