Android ライブラリの作成

Android ライブラリは、構造上は Android アプリ モジュールと同じです。ソースコード、リソース ファイル、Android マニフェストなど、アプリのビルドに必要なものはすべて含めることができます。ただし、Android ライブラリをコンパイルすると、デバイスで実行する APK ではなく、Android アプリ モジュールの依存関係として使用できる AAR(Android Archive)ファイルになります。JAR ファイルとは異なり、AAR ファイルには Android リソースとマニフェスト ファイルを含めることができるため、Java クラスやメソッド以外に、レイアウトやドローアブルといった共有リソースにもバンドルできます。

ライブラリ モジュールは、次のような場合に便利です。

  • アクティビティ、サービス、UI レイアウトといった同じコンポーネントを使用する複数のアプリをビルドする場合
  • 無償版と有償版などの複数の APK バリアントに存在するアプリをビルドするとき、同じコア コンポーネントを必要とする場合

どちらの場合も、再利用したいファイルをライブラリ モジュールに移動して、各アプリ モジュールの依存関係としてライブラリを追加するだけです。このページでは、両方のケースについて説明します。

ライブラリ モジュールを作成する

プロジェクトで新しいライブラリ モジュールを作成するには、次の手順を行います。

  1. [File] > [New] > [New Module] をクリックします。
  2. 表示された [Create New Module] ウィンドウで、[Android Library]、[Next] の順にクリックします。

    Java ライブラリを作成することもできますが、その場合は従来の JAR ファイルが作成されます。JAR ファイルは多くのプロジェクトで、特に他のプラットフォームとコードを共有する場合に役立ちますが、Android リソースやマニフェスト ファイルを含めることはできません(この特徴は、Android プロジェクトでコードを再利用する場合には非常に便利です)。そのためこのガイドでは、Android ライブラリの作成に焦点を当てて説明します。

  3. ライブラリの名前を指定し、ライブラリのコードの最小 SDK バージョンを選択して、[Finish] をクリックします。

Gradle プロジェクトの同期が完了したら、左側の [Project] パネルにライブラリ モジュールが表示されます。新しいモジュールのフォルダが表示されない場合は、[Android] ビューが表示されていることを確認します。

アプリ モジュールをライブラリ モジュールに変換する

再利用したいコードが含まれている既存のアプリ モジュールがある場合は、次の手順でライブラリ モジュールに変換できます。

  1. モジュール レベルの build.gradle ファイルを開きます。
  2. applicationId の行を削除します。これを定義できるのは Android アプリ モジュールだけです。
  3. ファイルの先頭に次の行があるはずです。
        apply plugin: 'com.android.application'
        

    この行を次のように変更します。

        apply plugin: 'com.android.library'
        
  4. ファイルを保存し、[File] > [Sync Project with Gradle Files] をクリックします。

これで完了です。モジュールの全体的な構造は同じままですが、Android ライブラリとして機能するようになりました。ビルドすると、APK ではなく AAR ファイルが作成されます。

AAR ファイルをビルドする場合は、[Project] ウィンドウでライブラリ モジュールを選択し、[Build] > [Build APK] をクリックします。

ライブラリを依存関係として追加する

Android ライブラリのコードを別のアプリ モジュールで使用するには、次の手順を行います。

  1. 次のいずれかの方法でライブラリをプロジェクトに追加します(同じプロジェクト内でライブラリ モジュールを作成済みの場合はすでにプロジェクト内に存在するため、この手順はスキップできます)。
    • コンパイル済みの AAR(または JAR)ファイルを追加する(ライブラリはすでにビルドされている必要がある):
      1. [File] > [New] > [New Module] をクリックします。
      2. [Import .JAR/.AAR Package]、[Next] の順にクリックします。
      3. コンパイル済みの AAR または JAR ファイルの場所を入力し、[Finish] をクリックします。
    • ライブラリ モジュールをプロジェクトにインポートする(ライブラリ ソースがプロジェクトの一部になる):
      1. [File] > [New] > [Import Module] をクリックします。
      2. ライブラリ モジュールのディレクトリの場所を入力し、[Finish] をクリックします。

      ライブラリ モジュールがプロジェクトにコピーされ、ライブラリ コードを実際に編集できるようになります。ライブラリ コードの単独のバージョンを維持したい場合はこの方法は適さないため、上記のようにコンパイル済みの AAR ファイルを追加する必要があります。

  2. settings.gradle ファイルの先頭にライブラリが記載されていることを確認します。ライブラリ名が「my-library-module」の場合は次のようになります。
        include ':app', ':my-library-module'
        
  3. アプリ モジュールの build.gradle ファイルを開き、次のスニペットに示すように、dependencies ブロックに新しい行を追加します。
        dependencies {
            implementation project(":my-library-module")
        }
        
  4. [Sync Project with Gradle Files] をクリックします。

上の例では、implementation の設定により、my-library-module という名前のライブラリがアプリ モジュール全体のビルド依存関係として追加されます。このライブラリが特定のビルド バリアントでのみ必要な場合は、implementation ではなく buildVariantNameImplementation を使用します。たとえば、「pro」プロダクト フレーバーにのみライブラリを含める場合は次のようにします。

    productFlavors {
        pro { ... }
    }
    dependencies {
        proImplementation project(":my-library-module")
    }
    

これで、アプリ モジュールから Android ライブラリのすべてのコードとリソースにアクセスできるようになりました。ライブラリの AAR ファイルはビルド時に APK にバンドルされます。

AAR ファイルを個別に共有する必要がある場合は、project-name/module-name/build/outputs/aar/ に AAR ファイルがあります。また、[Build] > [Make Project] をクリックしてこのファイルを再生成することもできます。

: 依存関係の管理について詳しくは、バリアント識別による依存関係の管理の使用をご覧ください。

公開するリソースを選択する

ライブラリ内のリソースはデフォルトですべてパブリックになります。すべてのリソースを暗黙的にプライベートにするには、少なくとも 1 つの属性をパブリックとして定義する必要があります。リソースには、プロジェクトの res/ ディレクトリにあるすべてのファイル(画像など)が含まれます。内部での利用に限定したリソースにライブラリのユーザーがアクセスできないようにするには、1 つ以上のパブリック リソースを宣言して、この自動プライベート指定の仕組みを利用する必要があります。また、空の <public /> タグを追加することによってすべてのリソースをプライベートにすることもできます(パブリックとして何もマークされないため、すべてのリソースがプライベートになります)。

パブリック リソースを宣言するには、<public> 宣言をライブラリの public.xml ファイルに追加します。これまでにパブリック リソースを追加したことがない場合は、ライブラリの res/values/ ディレクトリに public.xml ファイルを作成する必要があります。

次のサンプル コードでは、mylib_app_namemylib_public_string という名前の 2 つのパブリック文字列リソースを作成しています。

    <resources>
        <public name="mylib_app_name" type="string"/>
        <public name="mylib_public_string" type="string"/>
    </resources>
    

ライブラリを使用するデベロッパーに対して公開するリソースは、すべてパブリックにする必要があります。

暗黙的に属性をプライベートにすると、ライブラリの内部リソースがコード補完候補としてライブラリのユーザーに表示されなくなります。さらに、ライブラリのクライアントに悪影響を及ぼすことなくプライベート リソースの名前変更や削除が可能になります。プライベート リソースはコード補完から除外され、プライベート リソースを参照しようとすると Lint で警告が表示されます。

ライブラリを作成すると、Android Gradle プラグインがパブリック リソースの定義を取得して public.txt ファイルに抽出します。さらに、このファイルは AAR ファイル内にパッケージ化されます。

ライブラリ モジュールの開発に関する考慮事項

ライブラリ モジュールとそれに依存するアプリを開発するときは、次の動作と制限に注意してください。

ライブラリ モジュールへの参照を Android アプリ モジュールに追加すると、各参照の相対的な優先度を設定できます。ビルド時に、ライブラリが優先度の低い方から 1 つずつアプリに統合されます。

  • リソース統合時の競合

    ビルドツールは、ライブラリ モジュールのリソースとそれに依存するアプリ モジュールのリソースを統合します。指定されたリソース ID が両方のモジュールで定義されている場合は、アプリのリソースが使用されます。

    複数の AAR ライブラリで競合が発生すると、依存関係リストの最初(dependencies ブロックの先頭)に記載されているライブラリのリソースが使用されます。

    共通するリソース ID におけるリソースの競合を回避するには、モジュールごとに一意になるように(またはすべてのプロジェクト モジュールで一意になるように)接頭辞などの一貫性のある命名スキームの使用を検討してください。

  • マルチモジュール ビルドでは、JAR の依存関係が推移的な依存関係として扱われる

    AAR を出力するライブラリ プロジェクトに JAR の依存関係を追加すると、JAR がライブラリ モジュールによって処理され、AAR と一緒にパッケージ化されます。

    ただし、アプリ モジュールで使用されるライブラリ モジュールがプロジェクトに含まれている場合、アプリ モジュールはライブラリのローカル JAR の依存関係を推移的な依存関係として扱います。この場合、ローカル JAR は、ライブラリ モジュールではなく、ローカル JAR を使用するアプリ モジュールによって処理されます。これにより、ライブラリのコード変更によって生じる増分ビルドが高速化されます。

    ローカル JAR の依存関係に起因する Java リソースの競合は、ライブラリを使用するアプリ モジュールで解決する必要があります。

  • ライブラリ モジュールは外部 JAR ライブラリに依存できる

    外部ライブラリ(たとえば、Maps 外部ライブラリ)に依存するライブラリ モジュールを作成できます。この場合、依存するアプリは外部ライブラリ(たとえば、Google API アドオン)を含むターゲットを指定してビルドする必要があります。また、ライブラリ モジュールとそれに依存するアプリの両方のマニフェスト ファイルの <uses-library> 要素で外部ライブラリを宣言する必要があります。

  • アプリ モジュールの minSdkVersion には、ライブラリで定義されているバージョン以上の値を指定する必要がある

    ライブラリは、それに依存するアプリ モジュールの一部としてコンパイルされるため、ライブラリ モジュールで使用される API は、アプリ モジュールがサポートするプラットフォーム バージョンと互換性がなければなりません。

  • ライブラリ モジュールごとに独自の R クラスを作成する

    依存するアプリ モジュールをビルドすると、ライブラリ モジュールは AAR ファイルにコンパイルされた後、アプリ モジュールに追加されます。そのため、ライブラリごとに独自の R クラスが生成され、ライブラリのパッケージ名に従って命名されます。メイン モジュールとライブラリ モジュールから生成される R クラスは、メイン モジュールのパッケージとライブラリのパッケージを含め、必要なすべてのパッケージで作成されます。

  • ライブラリ モジュールには独自の ProGuard 設定ファイルを含めることができる

    AAR をビルドして公開するライブラリ プロジェクトの場合、ライブラリのビルド設定に ProGuard 設定ファイルを追加することで、指定した ProGuard ルールが Android Gradle プラグインによって適用されます。ビルドツールは、生成されたライブラリ モジュールの AAR ファイルにこのファイルを埋め込みます。アプリ モジュールにこのライブラリを追加すると、ライブラリの ProGuard ファイルがアプリ モジュールの ProGuard 設定ファイル(proguard.txt)に追加されます。

    ライブラリ モジュールに ProGuard ファイルを埋め込むことにより、ライブラリに依存するアプリ モジュールでライブラリを使用するために手動で ProGuard ファイルを更新する必要がなくなります。Android アプリ モジュールで ProGuard を実行すると、アプリ モジュールとライブラリの両方のディレクティブを使用するため、ライブラリ単独で ProGuard を実行しないようにしてください。

    ProGuard ルールをライブラリ プロジェクトに追加する場合は、ライブラリの build.gradle ファイルの defaultConfig ブロック内にある consumerProguardFiles プロパティでファイルの名前を指定する必要があります。たとえば次のスニペットでは、ライブラリの ProGuard 設定ファイルとして lib-proguard-rules.txt を設定しています。

        android {
            defaultConfig {
                consumerProguardFiles 'lib-proguard-rules.txt'
            }
            ...
        }
        

    ただし、APK にコンパイルされ、AAR を生成しないマルチモジュール ビルドにライブラリ モジュールが含まれている場合は、ライブラリを使用するアプリ モジュールでのみ ProGuard を実行するようにしてください。ProGuard ルールとその使用方法について詳しくは、コードとリソースの圧縮をご覧ください。

  • ライブラリ モジュールのテストはアプリのテストと同じ

    主な違いは、ライブラリとその依存関係がテスト APK の依存関係として自動的に含まれることです。つまり、テスト APK には独自のコードだけでなく、ライブラリの AAR とそのすべての依存関係も含まれます。「テスト中のアプリ」が単独で存在することはないため、androidTest タスクではテスト APK のみがインストール(およびアンインストール)されます。

    複数のマニフェスト ファイルを統合する場合、Gradle はデフォルトの優先順位に従って、ライブラリのマニフェストをテスト APK のメイン マニフェストに統合します。

AAR ファイルの仕組み

AAR ファイルのファイル拡張子は .aar で、Maven アーティファクト タイプにも aar を指定する必要があります。ファイル自体は、次の必須エントリを含む zip ファイルです。

  • /AndroidManifest.xml
  • /classes.jar
  • /res/
  • /R.txt
  • /public.txt

また、AAR ファイルには次のオプション エントリを 1 つ以上含めることができます。

  • /assets/
  • /libs/name.jar
  • /jni/abi_name/name.so(abi_name は、Android がサポートする ABI のいずれか)
  • /proguard.txt
  • /lint.jar
  • /api.jar