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 ライブラリのほうがはるかに便利です。よって、このガイドでは Android ライブラリの作成に焦点を当てて説明します。

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

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

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

既存のアプリ モジュールと再利用したいすべてのコードが用意できたら、次の手順でライブラリ モジュールに変換できます。

  1. 既存のアプリ モジュールの build.gradle ファイルを開きます。ファイルの先頭に次のように記載されています。
    apply plugin: 'com.android.application'
    
  2. プラグインの割り当てを次のように変更します。

    apply plugin: 'com.android.library'
    
  3. [Sync Project with Gradle Files] をクリックします。

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

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

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

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

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

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

上記の例では、build.gradle ファイルが存在するモジュールは、my-library- module という Android ライブラリ モジュールとビルドの依存関係があります。

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

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

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

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

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

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

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

ライブラリを使用するデベロッパーに表示したいリソースは、すべてパブリックにしてください。たとえば、v7 appcompat ライブラリ内のほとんどのリソースはプライベートですが、マテリアル デザインをサポートするため、ツールバー ウィジェットを制御する属性はパブリックになっています。

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

開発時の考慮事項

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

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

  • リソース統合時の競合

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

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

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

  • ライブラリ モジュールに JAR ライブラリをインクルードできる

    ライブラリ モジュール自体に JAR ライブラリを含めることができます。ただし手動で、依存するアプリ モジュールのビルドパスを編集し、JAR ファイルへのパスを追加する必要があります。

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

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

  • ライブラリ モジュールに未加工のアセットを含めることはできない

    このツールでは、ライブラリ モジュールの(assets/ ディレクトリに保存された)未加工のアセット ファイルの使用はサポートされていません。アプリで使用するアセット リソースはすべて、アプリ モジュール自体の assets/ ディレクトリに保存する必要があります。

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

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

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

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

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

    ProGuard ディレクティブを含むライブラリに ProGuard 設定ファイルを追加することで、ライブラリのコード圧縮を有効化できます。ビルドツールは、生成されたライブラリ モジュールの AAR ファイルにこのファイルを埋め込みます。アプリ モジュールにこのライブラリを追加すると、ライブラリの ProGuard ファイルがアプリ モジュールの ProGuard 設定ファイル(proguard.txt)に追加されます。

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

    ライブラリの設定ファイルの名前を指定するには、ライブラリの build.gradle ファイルの defaultConfig ブロックで consumerProguardFiles メソッドに名前を追加します。たとえば、次のスニペットではライブラリの ProGuard 設定ファイルとして lib-proguard-rules.txt を設定します。

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

    デフォルトで、アプリ モジュールのデバッグ ビルドタイプを使用するときでも、アプリ モジュールはライブラリのリリースビルドを使用します。ライブラリの別のビルドタイプを使用するには、アプリの build.gradle ファイルの dependencies ブロックに依存関係を追加し、ライブラリの build.gradle ファイルで publishNonDefaulttrue に設定する必要があります。たとえば、アプリの build.gradle ファイルに次のコード スニペットが存在すると、アプリがデバッグ モードでアプリ モジュールをビルドするときはライブラリのデバッグ ビルドタイプを使用し、アプリ モジュールをリリース モードでビルドするとライブラリのリリース ビルドタイプを使用します。

    dependencies {
        debugCompile project(path: ':library', configuration: 'debug')
        releaseCompile project(path: ':library', configuration: 'release')
    }
    

    また、ライブラリの非リリース設定を使用するプロジェクトにこの設定を公開するには、ライブラリの build.gradle ファイルの android ブロックに次の行を追加する必要があります。

    android {
        ...
        publishNonDefault true
    }
    

    ただし、publishNonDefault を設定すると、ビルド時間が長くなる可能性があります。

    ライブラリの ProGuard ルールによって、アプリ モジュールに望ましくない圧縮の副作用が生じるのを回避するには、ライブラリと連携しない ProGuard 機能を無効にするルールを含めるだけです。デベロッパーの支援を目的としたルールは、アプリ モジュールの既存のコードやその他のライブラリと競合する可能性があるため、含めないでください。たとえば、ライブラリの ProGuard ファイルでは、アプリ モジュールの圧縮時に維持する必要があるコードを指定できます。

    注: Jack ツールチェーンは、ProGuard を使用した圧縮オプションと難読化オプションの一部のみをサポートしています。

AAR ファイルの仕組み

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

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

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

  • /assets/
  • /libs/name.jar
  • /jni/abi_name/name.soabi_name は Android がサポートする ABI のうちいずれか 1 つ)
  • /proguard.txt
  • /lint.jar