web-dev-qa-db-ja.com

Androidアプリのapkサイズを縮小する方法openCv libが必要なアプリ(画像処理のみ))

私は、Androidアプリで最小SDK 15を使用してアプリを構築しています。これは、OpenCVライブラリを使用しています。問題は、それがapkサイズの60 MBを超えているため、あまり大きくありません。

アプリファイルを確認したところ、libopencv_Java3.soarmeabimipsamr64などのすべてのアーキテクチャでx86ファイルが原因でサイズが大きすぎることがわかりました。

enter image description here

私は画像処理にのみopneCvを使用しています。このライブラリには、ビデオ処理、3D画像、オブジェクト検出など、アプリに必要のない他の多くの機能があります。

これらのファイルをすべて削除してAPKをビルドすると、サイズは50 MB減少しますが、このアプリを機能させるには、アプリを実行するためにOpenCVManagerをインストールする必要があります。

APKサイズを小さくする方法はありますか?

または、私が興味のあるOpenCVから機能のみを抽出し、それらの機能の.soを作成することは可能ですか?

20
Shakeeb Ayaz

私にとっては、 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を保持するようにしてください。

8
Shakeeb Ayaz

ライブラリlibopencv_Java3.soは削除できません。これは必須です。

APKサイズを小さくする方法はありますか?

ライブラリlibopencv_Java3.soを変更せずに、フラットAPKをパッケージ化するのではなく、異なるアーキテクチャ用の複数のAPKを構築できます。分割APKにパッケージ化されるlibopencv_Java3.soのArchは1つだけです。たとえば、以下の設定を使用して、x86armeabi-v7abuild.gradlemipsアーキテクチャのみをビルドできます。

splits {
    abi {
      enable true
      reset()
      include "x86", "armeabi-v7a", "mips"
      universalApk false
    }
  }

分割によるapkサイズの削減の詳細については、 ここ を参照してください。

または、私が関心のあるOpenCVから機能のみを抽出して、それらの機能の.soを作成することは可能ですか?

はい、もちろん。 opencvのビルドプロセスは完全にカスタマイズされています。 Android向けのopencvのビルド方法をすでに知っている場合は、ステップ2に直接進んでください。

ステップ1

  1. opencv のソースを取得する
  2. ディレクトリを作成opencv_build
  3. クローンしたopencvのルートディレクトリに移動します
  4. ビルドスクリプトを呼び出す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.0Androidコマンドが削除されました。

ステップ2

上記のステップ1が適切に実行されていると想定します。ここでは、例としてarmeabi-v7aを取り上げます。

  1. ディレクトリopencv_build/o4a/lib/armeabi-v7aに移動します
  2. さまざまなopencvモジュールの多数の* .a、ライブラリlibopencv_Java3.soもこのディレクトリにあります
  3. 必要なモジュールから小さなバージョンの共有ライブラリを作成します。

    $ 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
    

coreimage codecsimage procを含む小さなバージョンは、ストリップ後のサイズは4.1Mですが、フルバージョンlibopencv_Java3.soのサイズは9.8M

便宜上、libopencv_tiny.soを名前として使用しています。プロジェクトでは同じ名前libopencv_Java3.soを使用する必要があります。それ以外の場合、JavaのSystem.loadLibraryはネイティブライブラリを見つけることができません。

必要な残りのアーキテクチャ、たとえばarm64-v8aについても同じようにします。

9
alijandro

上記の2つの答えは完全ですが、詳細と調整ノブが必要な場合に備えて、これを見つけてください 記事

0
Milind Deore

より多くのリソースサイズが含まれている場合は、gradleファイルで以下のコードを使用してください。プロジェクトから未使用のリソースを削除します。

 buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
        }
    }

未使用のコードを削除したい場合は、使用64Kメソッド

LINK2

OpenCVで質問を投稿することもできます

Q/Aサイト

0
Arpit Patel