Google Play でのビジネス拡大に役立つ無料のウェブセミナーにぜひご参加ください。今すぐ登録

64 ビット アーキテクチャをサポートする

2019 年 8 月 1 日以降、Google Play で公開するアプリは 64 ビット アーキテクチャをサポートする必要があります。64 ビット CPU は、高速かつリッチなエクスペリエンスをユーザーに提供します。64 ビット バージョンのアプリを追加することで、パフォーマンスを向上し、将来のイノベーションに備え、64 ビット ハードウェアのみで構成されたデバイスに対応できるようになります。

このガイドでは、32 ビット バージョンのアプリを 64 ビットデバイスで使用できるようにするために今すぐできることについて説明します。

アプリを評価する

すべてのライブラリや SDK を含め、Java プログラミング言語または Kotlin で記述されたコードだけを使用しているアプリの場合は、すでに 64 ビットデバイスに対応しています。アプリがネイティブ コードを使用している場合や、使用しているコードが不明な場合は、アプリを審査して対策を講じる必要があります。

クイック ステータス チェック

アプリが 64 ビット要件を満たしているかどうかを簡単にチェックするには、Play Console にアクセスして、既存のリリースが準拠しているか確認します。

また、ドラフト版リリースに 64 ビット要件に関連する問題があった場合は、Play Console 内に警告が表示されます。たとえば、次のようになります。

このようなアラートが表示された場合は、以下の手順に沿ってアプリの対応を行ってください。

アプリがネイティブ コードを使用しているか?

まず、アプリでネイティブ コードを使用しているかどうかを確認します。次の場合は、アプリでネイティブ コードを使用しています。

  • アプリで C/C++(ネイティブ)コードを使用している。
  • サードパーティのネイティブ ライブラリとリンクしている。
  • ネイティブ ライブラリを使用するサードパーティ製アプリビルダーでビルドされている。

アプリに 64 ビット ライブラリが含まれているか?

64 ビット ライブラリが含まれているかどうかを確認する場合、APK ファイルの構造を調べる方法が最も簡単です。APK はビルドの際に、アプリに必要なネイティブ ライブラリと一緒にパッケージ化されます。ネイティブ ライブラリは、ABI に基づいてさまざまなフォルダに格納されます。すべての 64 ビット アーキテクチャをサポートする必要はありませんが、サポート対象のネイティブ 32 ビット アーキテクチャごとに、対応する 64 ビット アーキテクチャを含める必要があります。

ARM アーキテクチャの場合、32 ビット ライブラリは armeabi-v7a に配置されます。64 ビット バージョンは arm64-v8a にあります。

x86 アーキテクチャの場合、32 ビット ライブラリは x86、64 ビット ライブラリは x86_64 にあります。

まず、これらのフォルダにネイティブ ライブラリがあるかどうかを確認します。まとめると次のようになります。

プラットフォーム 32 ビット ライブラリのフォルダ 64 ビット ライブラリのフォルダ
ARM lib/armeabi-v7a lib/arm64-v8a
x86 lib/x86 lib/x86_64

アプリによって、各フォルダにまったく同じライブラリ セットがある場合とない場合があります。目標は、アプリが 64 ビットのみの環境で正しく動作できるようにすることです。

通常、32 ビットと 64 ビットの両方のアーキテクチャ向けにビルドされた APK またはバンドルには両方の ABI 用にフォルダが用意され、それぞれに対応するネイティブ ライブラリ セットが格納されます。64 ビットがサポートされない場合、32 ビット用の ABI フォルダが作成され、64 ビット用のフォルダは作成されない可能性があります。

APK Analyzer を使用してネイティブ ライブラリを探す

APK Analyzer は、ビルドした APK のさまざまな要素を評価するためのツールです。ここでは、APK Analyzer を使用してネイティブ ライブラリを探し、64 ビット ライブラリが存在するかどうかを確認します。

  1. Android Studio を起動して、任意のプロジェクトを開きます
  2. メニューで、[Build] > [Analyze APK…] を選択します。

    APK Analyzer を起動する

  3. 評価する APK を選択します。

  4. lib フォルダ内を調べます。「.so」ファイルはこのフォルダ内にあります。アプリ内で「.so」ファイルが見つからない場合、そのアプリは対応済みのため、これ以上のアクションは必要ありません。armeabi-v7a または x86 が見つかった場合は、32 ビット ライブラリが存在します。

  5. arm64-v8a フォルダまたは x86_64 フォルダに同様の「.so」ファイルがあるかどうかを確認します。

    APK Analyzer を起動する

  6. arm64-v8a ライブラリまたは x86_64 ライブラリがない場合は、ビルドプロセスを更新し、アーティファクトをビルドして APK にパッケージ化します。

  7. 両方のライブラリがすでにパッケージ化されている場合は、64 ビット ハードウェアでアプリをテストするに進んでください。

APK を解凍してネイティブ ライブラリを探す

APK ファイルは ZIP ファイルに似た構造になっており、ZIP ファイルと同じように解凍することができます。コマンドラインやその他の抽出ツールを使用して APK を解凍することもできます。

APK ファイルを解凍し(抽出ツールによっては、ファイル名を .zip に変更しなければならない場合があります)、抽出したファイルを参照して、上記のガイダンスに従って 64 ビットデバイスに対応しているかどうかを確認します。

たとえば、コマンドラインから次のコマンドを実行できます。

:: Command Line
    > zipinfo -1 YOUR_APK_FILE.apk | grep \.so$
    lib/armeabi-v7a/libmain.so
    lib/armeabi-v7a/libmono.so
    lib/armeabi-v7a/libunity.so
    lib/arm64-v8a/libmain.so
    lib/arm64-v8a/libmono.so
    lib/arm64-v8a/libunity.so
    

この例では、armeabi-v7a ライブラリと arm64-v8a ライブラリが存在するため、アプリは 64 ビット アーキテクチャをサポートしています。

64 ビット ライブラリでアプリをビルドする

ここからは、64 ビット ライブラリをビルドする手順を説明します。ただし、ソースからビルド可能なコードとライブラリのビルドのみを対象としていることを理解しておいてください。

外部の SDK またはライブラリを使用している場合は、上記の手順に沿って 64 ビット バージョンを使用していることを確認してください。64 ビット バージョンを使用できない場合は、SDK またはライブラリの所有者に問い合わせてください。また、64 ビットデバイスのサポートを計画している場合も、この点を確認してください。

Android Studio または Gradle でのビルド

ほとんどの Android Studio プロジェクトでは基盤となるビルドシステムとして Gradle を使用するため、このセクションはどちらのケースにも適用されます。ネイティブ コードのビルドを有効にする方法は非常に簡単で、サポート対象のアーキテクチャに応じて arm64-v8ax86_64 をアプリの「build.gradle」ファイル内の ndk.abiFilters 設定に追加するだけです。

// Your app's build.gradle
    apply plugin: 'com.android.app'

    android {
       compileSdkVersion 27
       defaultConfig {
           appId "com.google.example.64bit"
           minSdkVersion 15
           targetSdkVersion 28
           versionCode 1
           versionName "1.0"
           ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
    // ...
    

CMake を使用してビルドする

CMake を使用してアプリをビルドする場合、arm64-v8a を「-DANDROID_ABI」パラメータに渡すことで、64 ビット ABI 用にビルドすることができます。

:: Command Line
    > cmake -DANDROID_ABI=arm64-v8a … or
    > cmake -DANDROID_ABI=x86_64 …
    

externalNativeBuild を使用している場合、このオプションの効果はありません。詳細については、Gradle を使用してビルドするをご覧ください。

ndk-build を使用してビルドする

ndk-build を使用してアプリをビルドする場合、APP_ABI 変数を使用して Application.mk ファイルを編集することで、64 ビット ABI 用にビルドすることができます。

APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
    

externalNativeBuild を使用している場合、このオプションの効果はありません。詳細については、Gradle を使用してビルドするをご覧ください。

32 ビットコードを 64 ビットに移植する

すでにパソコン上や iOS 上でコードを実行済みの場合、Android 向けに追加作業を行う必要はありません。元々 64 ビットシステム向けにビルドされているコードの場合、ポインタが int のような 32 ビット整数型に適合しなくなるため、対処する必要があります。int 型や unsigned 型、uint32_t 型などのポインタを格納するコードを更新する必要があります。Unix システムの場合は long とポインタサイズが一致しますが、Windows の場合は一致しないため、代わりに、意図が明確な uintptr_t 型や intptr_t 型を使用する必要があります。ptrdiff_t 型を使用すると、2 つのポインタ間の差を格納できます。

ポインタでない場合でも、intlong といった従来の型ではなく、<stdint.h> で定義されている特定の固定幅の整数型を使用するようにしてください。

次のコンパイラ フラグを使用して、ポインタと整数の間をコードが正しく変換できていない場所を検出します。

-Werror=pointer-to-int-cast
    -Werror=int-to-pointer-cast
    -Werror=shorten-64-to-32
    

C / C++ オブジェクトへのポインタを保持する int フィールドを持つ Java クラスの場合にも、同じ問題が発生します。JNI ソース内で jint を検索して、必ず Java 側では long に切り替え、C++ 側では jlong に切り替えてください。

暗黙的な関数宣言は、64 ビットコードの場合、危険度が大幅に増加します。C / C++ は、暗黙的に宣言された関数(コンパイラが宣言を認識していない関数)の戻り値の型を int だと想定します。関数の実際の戻り値の型がポインタであった場合、ポインタが int に適合する 32 ビットシステムでは正常に機能しますが、64 ビットシステムでは、コンパイラはポインタの上半分をドロップします。たとえば、次のようになります。

// This function returns a pointer:
    // extern char* foo();

    // If you don't include a header that declares it,
    // when the compiler sees this:
    char* result = foo();

    // Instead of compiling that to:
    result = foo();

    // It compiles to something equivalent to:
    result = foo() & 0xffffffff;

    // Which will then cause a SIGSEGV if you try to dereference `result`.
    

次のコンパイラ フラグは、暗黙的な関数宣言の警告をエラーに変換するため、この問題を簡単に見つけて修正することができます。

-Werror=implicit-function-declaration
    

インライン アセンブラがある場合は、書き換えるか、プレーンな C / C++ 実装を使用する必要があります。

型のサイズがハードコーディングされている場合(8 バイトや 16 バイトなど)、同等の sizeof(T) 式で置き換えます(sizeof(void*) など)。

64 ビット用コードとは異なる 32 ビット用コードを条件付きでコンパイルする必要がある場合は、汎用的な 32 ビット / 64 ビットの相違に対しては #if defined(__LP64__) を使用し、Android がサポートする個々のアーキテクチャに対しては __arm____aarch64__(arm64)、__i386__(x86)、__x86_64__ を使用することができます。

printfscanf のような関数の場合、従来のフォーマット指定子では 32 ビットと 64 ビットの両方のデバイスで正常に機能する方法で 64 ビット型を指定することができないため、フォーマット文字列を調整する必要があります。<inttypes.h> 内で PRI マクロや SCN マクロを使用すると、この問題を解決できます。16 進ポインタの書き込み / 読み取りには PRIxPTRSCNxPTR を使用し、移植する 64 ビット値の書き込み / 読み取りには PRId64SCNd64 を使用します。

シフトする際は、32 ビット専用の 1 を使用するのではなく、1ULL を使用して 64 ビット定数をシフトすることが必要となる場合があります。

Android App Bundle を使用してサイズの増大を緩和する

64 ビット アーキテクチャのサポートをアプリに追加すると、APK のサイズが増大することがあります。32 ビットと 64 ビットの両方のネイティブ コードを同じ APK に含める場合、サイズの影響を最小限に抑えるために、Android App Bundle 機能を利用することを強くおすすめします。

Android App Bundle を使用するようにアプリを切り替えると、APK サイズが改善され、現在のサイズよりも削減できる場合があります。

ゲーム デベロッパー

サードパーティ製のゲームエンジンの移行は、リードタイムの長い集中的なプロセスです。幸い、以下のよく使われている 3 つのエンジンはすべて、64 ビットをサポートしています。

  • Unreal(2015 年から)
  • Cocos2d(2015 年から)
  • Unity(2018 年から)

Unity デベロッパー

サポート バージョンへのアップグレード

Unity は、バージョン 2018.2 とバージョン 2017.4.16 で 64 ビットのサポートを開始しました。

64 ビットをサポートしていないバージョンの場合は、アップグレードするバージョンを決定し、Unity から提供されているガイドに従って環境を移行します。必ず、64 ビット ライブラリをビルド可能なバージョンにアプリがアップグレードされるようにしてください。Unity では、最新の LTS バージョンのエディタにアップグレードして、最新の機能とアップデートを利用するよう推奨しています。

以下の表に、Unity の各種バージョンと推奨事項を示します。

Unity のバージョン 64 ビットをサポートしているか? 推奨される行動指針

2018.4(LTS)

(リリース保留中)ビルド設定を調整して 64 ビット ライブラリが生成されるようにする。

2018.3

ビルド設定を調整して 64 ビット ライブラリが生成されるようにする。

2018.2

ビルド設定を調整して 64 ビット ライブラリが生成されるようにする。

2018.1

試験的に 64 ビットがサポートされている。

2017.4(LTS)

2017.4.16 以降サポート対象。ビルド設定を調整して 64 ビット ライブラリを生成するようにする。

2017.3

✖️

64 ビットをサポートしているバージョンにアップグレードする。

2017.2

✖️

64 ビットをサポートしているバージョンにアップグレードする。

2017.1

✖️

64 ビットをサポートしているバージョンにアップグレードする。

5.6 以下

✖️

64 ビットをサポートしているバージョンにアップグレードする。

ビルド設定を変更して 64 ビット ライブラリを生成するようにする

64 ビット版の Android ライブラリをサポートしているバージョンの Unity を使用している場合は、ビルド設定を調整することによって 64 ビット バージョンのアプリを生成できます。また、スクリプト バックエンドとして IL2CPP バックエンドを使用する必要もあります(詳細はこちら)。64 ビット アーキテクチャをビルドするように Unity プロジェクトを設定する手順は次のとおりです。

  1. [Build Settings] に移動して、Android 向けにビルドされることを確認します(Unity のマークが Android プラットフォームの横に表示されていることを確認します)。**
    1. Unity のマークが Android プラットフォームの横に表示されていない場合は、Android を選択して [Switch Platform] をクリックします。
  2. [Player Settings] をクリックします。

    Unity のプレーヤー設定

  3. [Player Settings] パネル > [Settings for Android] > [Other settings] > [Configuration] に移動します。

  4. [Scripting Backend] を [IL2CPP] に設定します。

  5. **[Target Architectures] の [ARM64] チェックボックスをオンにします。

    Unity でターゲット アーキテクチャを設定する

  6. 通常どおりにビルドします。

ARM64 向けのビルドでは、すべてのアセットを対象のプラットフォーム専用にビルドする必要があります。Unity のガイダンスに沿って、APK サイズを削減してください。また、サイズの増大を緩和するために、Android App Bundle 機能を利用することをおすすめします。

マルチ APK と 64 ビット コンプライアンス

Google Play のマルチ APK サポートを使用してアプリを公開する場合、64 ビット要件に準拠しているかどうかはリリースレベルで評価されます。ただし、Android 9 Pie 以降を搭載しているデバイスに配信しない APK やアプリバンドルであれば、64 ビット要件は適用されません。

APK のいずれかが「準拠していない」とマーキングされたときに、その APK が旧式で、準拠させることができない場合は、その APK のマニフェストの uses-sdk 要素に maxSdkVersion="27" 属性を追加することで、要件の問題を回避することができます。この APK は、Android 9 Pie 以降を搭載しているデバイスには配信されず、コンプライアンスを阻害しなくなります。

RenderScript と 64 ビット コンプライアンス

RenderScript を使用しているアプリが、古いバージョンの Android ツールでビルドされている場合、64 ビット コンプライアンスの問題が発生する可能性があります。21.0.0 より前のビルドツールの場合、コンパイラが外部 .bc ファイル内にビットコードを生成していることがあります。このような旧式の .bc ファイルは 64 ビット アーキテクチャではサポートされなくなったため、APK 内にそのファイルが存在することが原因で、コンプライアンスの問題が発生します。

この問題を解決するには、プロジェクト内の .bc ファイルをすべて削除して、環境を build-tools-21.0.0 以降にアップグレードし、Android Studio 内で renderscriptTargetApi を 21+ に設定することで、コンパイラに .bc ファイルを生成しないように指示します。そして、アプリを再ビルドし、.bc ファイルがないか検査して、Play Console にアップロードします。

64 ビット ハードウェア上でアプリをテストする

64 ビット バージョンのアプリは、32 ビット バージョンと同じ品質と機能を提供できる必要があります。アプリをテストして、ユーザーが最新の 64 ビットデバイスでアプリを快適に操作できることを確認します。

アプリのテストを開始するには、64 ビット対応のデバイスが必要です。64 ビット対応のデバイスとして、Google の Pixel やその他のフラグシップ デバイスなど、さまざまな人気機種を使用できます。

APK の最も簡単なテスト方法は、adb を使用してアプリをインストールする方法です。ほとんどの場合、デバイスにインストールするライブラリを示すパラメータとして --abi を指定できます。これにより、64 ビット ライブラリのみを使用するアプリがデバイスにインストールされます。

:: Command Line
    # A successful install:
    > adb install --abi armeabi-v7a YOUR_APK_FILE.apk
    Success

    # If your APK does not have the 64-bit libraries:
    > adb install --abi arm64-v8a YOUR_APK_FILE.apk
    adb: failed to install YOUR_APK_FILE.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]

    # If your device does not support 64-bit, an emulator, for example:
    > adb install --abi arm64-v8a YOUR_APK_FILE.apk
    ABI arm64-v8a not supported on this device
    

インストールが成功したら、通常どおりにアプリをテストして、32 ビット バージョンと品質が同じであることを確認します。

公開

アプリの準備ができたら、通常どおりに公開します。いつものように、アプリのデプロイに関するおすすめの方法に従ってください。アプリの品質が変わっていないことを確認するためには、クローズド テスト版のトラックを利用して一部のユーザーにのみ公開することをおすすめします。

メジャー アップデートの公開時と同様に、64 ビット対応のデバイスで徹底的にテストを行ってから多くのユーザーに公開してください。