私は、Androidアプリで最小SDK 15
を使用してアプリを構築しています。これは、OpenCVライブラリを使用しています。問題は、それがapkサイズの60
MBを超えているため、あまり大きくありません。
アプリファイルを確認したところ、libopencv_Java3.so
、armeabi
、mips
、amr64
などのすべてのアーキテクチャでx86
ファイルが原因でサイズが大きすぎることがわかりました。
私は画像処理にのみopneCvを使用しています。このライブラリには、ビデオ処理、3D画像、オブジェクト検出など、アプリに必要のない他の多くの機能があります。
これらのファイルをすべて削除してAPKをビルドすると、サイズは50 MB減少しますが、このアプリを機能させるには、アプリを実行するためにOpenCVManager
をインストールする必要があります。
APKサイズを小さくする方法はありますか?
または、私が興味のあるOpenCV
から機能のみを抽出し、それらの機能の.so
を作成することは可能ですか?
私にとっては、 alijandro回答 2番目の回答が最良の解決策でしたが、プロセスで立ち往生しました。そのため、apk splitで問題を解決しました。プラットフォームに関連するapkと、ユニバーサルapkをアップロードする必要があります。 OpenCVはモジュールレベルで追加の依存関係を提供しないため、理想的です。
ユニバーサルapkは、プラットフォームが一致しない場合にダウンロードされます。 ここ は、apk公開mutiple apkについて上手に書かれたブログです。同じアプリID、キーストア、同じアプリバージョンを維持する必要がありますが、コードバージョンが異なります
ステップ1。spk分割用のGradleコードを追加します。個別のapkを作成するアーキテクチャを含めます。
Android{
//......
splits {
abi {
enable true
reset()
include "armeabi","armeabi-v7a",'arm64-v8a',"mips","x86","x86_64",'arm64-v8a'
universalApk true
}
}
}
ステップ2。プラットフォームごとに異なるコードバージョンのコードを追加します。
Android{
//......
}
ext.versionCodes = ['armeabi': 3, 'armeabi-v7a': 4, 'arm64-v8a': 5,
mips: 6, 'x86': 7, 'x86_64': 8]
import com.Android.build.OutputFile
// For each APK output variant, override versionCode with a combination
// of ABI APK value * 1000 + defaultConfig.versionCode
Android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
def abiFilter = output.getFilter(OutputFile.ABI)
def abiMultiplier = 0
if (abiFilter != null) {
abiMultiplier = project.ext.versionCodes.get(abiFilter)
}
output.versionCodeOverride =
abiMultiplier * 1000 + Android.defaultConfig.versionCode
}
}
たとえば、初期バージョンコードが1の場合、生成されるコードは次のようになります。
armeabi -> 3001
armeabi-v7a -> 4001
arm64-v8a -> 5001
mips -> 6001
x86 -> 7001
x86_64 -> 8001
まとめると、Gradleコードは次のようになります。
Android{
//......
splits {
abi {
enable true
reset()
include "armeabi","armeabi-v7a",'arm64-
v8a',"mips","x86","x86_64",'arm64-v8a'
universalApk true
}
}
ext.versionCodes = ['armeabi': 3, 'armeabi-v7a': 4, 'arm64-v8a': 5,
mips: 6, 'x86': 7, 'x86_64': 8]
import com.Android.build.OutputFile
Android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def abiFilter = output.getFilter(OutputFile.ABI)
def abiMultiplier = 0
if (abiFilter != null) {
abiMultiplier = project.ext.versionCodes.get(abiFilter)
}
output.versionCodeOverride =
abiMultiplier * 1000 + Android.defaultConfig.versionCode
}
}
次に、playstoreですべてのAPKを1つずつ公開する必要があります。
注:公開中は、すべてのプラットフォームとユニバーサルAPKを保持するようにしてください。
ライブラリlibopencv_Java3.so
は削除できません。これは必須です。
APKサイズを小さくする方法はありますか?
ライブラリlibopencv_Java3.so
を変更せずに、フラットAPKをパッケージ化するのではなく、異なるアーキテクチャ用の複数のAPKを構築できます。分割APKにパッケージ化されるlibopencv_Java3.so
のArchは1つだけです。たとえば、以下の設定を使用して、x86
のarmeabi-v7a
、build.gradle
、mips
アーキテクチャのみをビルドできます。
splits {
abi {
enable true
reset()
include "x86", "armeabi-v7a", "mips"
universalApk false
}
}
分割によるapkサイズの削減の詳細については、 ここ を参照してください。
または、私が関心のあるOpenCVから機能のみを抽出して、それらの機能の.soを作成することは可能ですか?
はい、もちろん。 opencv
のビルドプロセスは完全にカスタマイズされています。 Android向けのopencvのビルド方法をすでに知っている場合は、ステップ2に直接進んでください。
opencv_build
opencv
のルートディレクトリに移動しますplatforms/Android/build_sdk.py --ndk_path $Android_NDK_ROOT --sdk_path $Android_SDK_ROOT ../opencv_build .
ビルド手順ではapkをビルドするためにAndroid
コマンドが必要なので、Android SDKツールのバージョンは25.3.0
未満である必要があります25.3.0
、Android
コマンドが削除されました。
上記のステップ1が適切に実行されていると想定します。ここでは、例としてarmeabi-v7a
を取り上げます。
opencv_build/o4a/lib/armeabi-v7a
に移動しますlibopencv_Java3.so
もこのディレクトリにあります必要なモジュールから小さなバージョンの共有ライブラリを作成します。
$ arm-linux-androideabi-gcc -shared -o libopencv_tiny.so --sysroot=$Android_NDK_ROOT/platforms/Android-9/Arch-arm -Wl,--whole-archive libopencv_core.a libopencv_imgcodecs.a libopencv_imgproc.a -Wl,--no-whole-archive
$ du -h libopencv_tiny.so
5.2M libopencv_tiny.so
$ arm-linux-androideabi-strip --strip-unneeded libopencv_tiny.so
$ du -h libopencv_tiny.so
4.1M libopencv_tiny.so
$ du -h libopencv_Java3.so
9.8M libopencv_Java3.so
core
、image codecs
、image proc
を含む小さなバージョンは、ストリップ後のサイズは4.1M
ですが、フルバージョンlibopencv_Java3.so
のサイズは9.8M
。
便宜上、libopencv_tiny.so
を名前として使用しています。プロジェクトでは同じ名前libopencv_Java3.so
を使用する必要があります。それ以外の場合、JavaのSystem.loadLibrary
はネイティブライブラリを見つけることができません。
必要な残りのアーキテクチャ、たとえばarm64-v8a
についても同じようにします。
上記の2つの答えは完全ですが、詳細と調整ノブが必要な場合に備えて、これを見つけてください 記事 。