web-dev-qa-db-ja.com

さまざまなAndroidアーキテクチャをターゲットにする方法は?

現在、NDKを使用しないOpenCV(OpenCV4Android)ライブラリを使用しています(CまたはC++コードはありません)。ただし、armeabi、armeabi-v7a、mips、およびx86用の.soファイルがあります。これらすべてをプロジェクトに含めると、アプリのサイズは30 MBになりますが、1つだけ含めると、アプリのサイズは9MBになります。そのデバイスのアーキテクチャの.soファイルが含まれていないデバイスでアプリを実行しようとすると、クラッシュしますが、.soファイルが含まれている場合は機能します。

したがって、ファイルサイズを小さくするために、複数のAPKを異なるデバイスアーキテクチャにリリースしたいと考えています。私が見たところ、これはApplication.mkファイルでのみ実行できますが、私のライブラリにはありません。異なるAndroidアーキテクチャをターゲットにする別の方法はありますか?

9
AggieDev

現在、NDKを使用しないOpenCV(OpenCV4Android)ライブラリを使用しています(CまたはC++コードはありません)。ただし、armeabi、armeabi-v7a、mips、およびx86用の.soファイルがあります。

Immibisが言っているように、.soファイルがある場合は、NDKを使用しています。

そのデバイスのアーキテクチャの.soファイルが含まれていないデバイスでアプリを実行しようとすると、クラッシュしますが、.soファイルが含まれている場合は機能します。

それはデバイスによって異なります。多くのx86デバイスにはlibhoudiniがあり、ネイティブx86バイナリを実行するよりも低速ですが、ARM NDKバイナリを実行できます。同様に、armeabi-v7デバイスはarmeabiNDKバイナリを実行できます。特に浮動小数点処理が使用されている場合は、より遅くなります。

したがって、ファイルサイズを小さくするために、複数のAPKを異なるデバイスアーキテクチャにリリースしたいと考えています。私が見たところ、これはApplication.mkファイルでのみ実行できますが、私のライブラリにはありません。

Application.mkファイルは、コンパイルされるもののみを制御し、配布されるものは制御しません。

異なるAndroidアーキテクチャをターゲットにする別の方法はありますか?

Gradle for Androidを、おそらくAndroid Studio、および abi split と組み合わせて使用​​します。

Android {
  ...
  splits {
    abi {
      enable true
      reset()
      include 'x86', 'armeabi-v7a', 'mips'
      universalApk true
    }
  }
}

abiクロージャのsplitsクロージャ:

  • cPUアーキテクチャごとに異なるAPKファイルを持つことを選択します

  • 必要なアーキテクチャのホワイトリストを設定します

  • また、アーキテクチャごとに個別のAPKをサポートしない流通チャネルで使用するために、すべてのアーキテクチャを含む「ユニバーサルAPK」をリクエストします

ビルドの結果は、CPUアーキテクチャごとに個別のAPKに加えて、ユニバーサルAPKになります。

18
CommonsWare

アプリケーションの各apkには、Android:versionCodeで指定された一意のバージョンコードが必要です。一部のx86デバイスはARMv7バイナリを実行できます。したがって、ARMv7 apkがx86デバイスでダウンロード/使用されるケース(および他のアーキテクチャの同様のシナリオ)を回避するには、バージョンコードを注文する必要があります。たとえば、x86APKのバージョンコードがARMv7よりも高くなるようにバージョンコードを注文します。これでバージョン管理の詳細 リンク

選択したアーキテクチャごとに一意のバージョンコード化APKを作成するためのbuild.gradleサンプルは、ph0bによって github で共有されます。以下に同じものをコピーします。

splits {
        abi {
            enable true
            reset()
            include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
            universalApk true //generate an additional APK that contains all the ABIs
        }
    }

    // map for the version code
    project.ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'arm64-v8a': 3, 'mips': 5, 'mips64': 6, 'x86': 8, 'x86_64': 9]

    Android.applicationVariants.all { variant ->
        // assign different version code for each output
        variant.outputs.each { output ->
            output.versionCodeOverride =
                    project.ext.versionCodes.get(output.abiFilter, 0) * 1000000 + Android.defaultConfig.versionCode
        }
    }

提案:Android複数のapkのサポート ドキュメント複数のapkを使用しないことを提案しますapkサイズが50mb未満の場合

さまざまなデバイス構成に必要な代替リソースのためにAPKが大きすぎる(50MBを超える)場合にのみ、通常、複数のAPKを使用してさまざまなデバイス構成をサポートする必要があります。単一のAPKを使用してさまざまな構成をサポートすることは、アプリケーションの更新パスがユーザーにとってシンプルで明確になるため(また、開発と公開の複雑さを回避することで作業が簡単になるため)、常にベストプラクティスです。

10
Kiran

このパターンを使用してビルド番号を作成することはお勧めしません。 Arch-BUILD、ある日1つのAPKに戻りたい場合は、versionCodeを大幅に増やす必要があるためです。代わりに、次のパターンに従うことができます:BUILD-Arch

Android.defaultConfig.versionCode * 100 + project.ext.versionCodes.get(output.getFilter(com.Android.build.OutputFile.ABI), 0)

ビルド74の例:ビルド番号は次のようになります:7402-armeabi-v7a 7408-x86

3
sonique