TL;DR: 本書では、日々の Android 開発に役立つ 15 のライブラリを簡単に見ていきます。これらを使って、より良いパフォーマンスとより良いユーザー エクスペリエンスを提供するアプリケーションを作成することができます。

「大人気の Android ライブラリはより良いパフォーマンスとユーザーエクスペリエンスを提供するアプリケーションの作成に役立ちます。」

大人気の Android ライブラリ

ライブラリはプラットフォームやスタックに関連付けられたソフトウェア開発に大変革をもたらします。ライブラリを使って、他の開発者の作業を利用して、より重要度の低い定型句コードでより早く、より効果的にアクション/機能を実行します。本書では、Android 開発におけるさまざまなカテゴリやそれらに使用される共通ライブラリについて学んでいきます。

Android ライブラリ — 画像読み込み

画像読み込みライブラリは複数の画像を同時に読み込んで大量のメモリが消費されないようにするときにとても便利です。画像は Android 開発で起きるメモリ不足エラーの最大の源です。よって、これらライブラリはシームレスなユーザーエクスペリエンスを提供するためにメモリ使用量を最小限にして、画像を読み込んだりキャッシュしたりする面倒を減らします。おなじみの 2 つの画像読み込みライブラリ、Glide と Picasso を見てみましょう。

Glide

Glide はスムーズなスクロールにフォーカスした画像読み込みライブラリです。Glide は、ストレージ オーバーヘッドとデコード時間を最小限にするために自動式スマート ダウンサンプリングとキャッシュを画像読み込みを適用して、できるだけ速くかつスムーズに行います。また、バイト配列のようなリソースを再利用し、必要なときにアプリケーションリソースを自動的にリリースします。Glide の最新バージョンは書き込みのときに SDK の API レベル 14 (Android 4.0)以上、SDK の API 26 (Android 8.0)以降のコンパイルが必要です。

GLIDE を使用する

まず、プロジェクト build.gradle ファイルに Maven および Google レポジトリを次のように追加します。

repositories {
  mavenCentral()
  google()
}

それから、アプリモジュール build.gradle ファイルにライブラリ依存関係を追加して、それを同期して次のようにライブラリを使用可能にします。

implementation 'com.github.bumptech.glide:glide:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'

すると、次のように 1 行のコードでリモート URL から画像をロードできます。

GlideApp
  .with(this)
  .load("https://res.cloudinary.com/demo/video/upload/dog.png")
  .into(imageView);

with メソッドは ContextActivityFragment または View オブジェクトを取ることができます。 load メソッドはリモート URL またはドローアブルファイル(例 R.drawable.image)を取ります。引数として intoメソッドにパスされた imageView インスタンスはタイプ ImageView であるべきです。

gradle バージョンが 3.0 以下の場合は、依存関係を追加するために implementation の代わりに compile キーワードを使用するように 注意してください

Picasso

Picasso はもうひとつの素晴らしい Android 用画像ライブラリです。オープンソースの世界に強く依存し、貢献する会社の Square が作成・管理しており、画像読み込み・処理を提供しています。Picasso を使用すると、画像を外部の場所から表示するプロセスが簡素化されます。Picasso は複雑な画像変換、ディスクへの自動キャッシュ、ImageView リサイクル、アダプタのダウンロード取り消しをサポートします。

このライブラリはプロセスの全ステップを処理します。HTTP 要求を処理することから始まり、画像のキャッシュも処理します。丁度 Glide と同様です。

PICASSO を使用する

まず、Picasso 依存関係を次のようにアプリモジュール build.gradle ファイルに追加します。

implementation 'com.squareup.picasso:picasso:2.5.2'

その後、gradle ファイルを同期し、次のように 1 行のコードで画像リソースをロードします。

Picasso
  .with(this)
  .load("https://res.cloudinary.com/demo/video/upload/dog.png")
  .into(imageView);

ご覧のように、Picasso が提供した API は Glide が提供したものと非常によく似ています。

長い間、どっちのライブラリのパフォーマンスが良いかということについて議論され、論争されてきました。以下の表には両者の長所と短所が記載されています。

Android Image Libraries Comparison

出典元:Glide vs Picasso

Android ライブラリ — ビデオ

ビデオの表示は開発の間に難しい作業が課せられます。処理するプロセスと詳細があまりにも多すぎるからです。この種では、利用可能なオプションがいくつかあります。しかし、最も普及していて強力なものは ExoPlayer で、この章ではこれについてフォーカスしていきます。

ExoPlayer

ExoPlayer は Google が開発した Android Media Player ライブラリです。オーディオとビデオを再生するときに(ローカルとインターネット上の両方で)Android の MediaPlayer API に代替オプションが与えられ、他の利点もあります。ExoPlayer は Android の MediaPlayer API が現在サポートしていない DASH や SmoothStreaming 適応型再生 のような機能を提供します。ExoPlayer の最大の利点のひとつはカスタマイズが簡単なことです。

EXOPLAYER を使用する

まず最初に、JCenter および Google レポジトリを次のようにプロジェクト build.gradle 構成ファイルに追加します。

repositories {
    jcenter()
    google()
}

次に、Gradle コンパイル依存関係を次のように同じファイルに追加します。

implementation 'com.google.android.exoplayer:exoplayer:2.6.0'

それから、レイアウトリソースファイルに SimpleExoPlayerView コンポーネントを次のように追加します。

<com.google.android.exoplayer2.ui.SimpleExoPlayerView
   android:id="@+id/simple_exoplayer_view"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"/>

その後、対応するアクティビティ クラスで、次のように ExoPlayer のクラスのインスタンスを作成します。

SimpleExoPlayerView simpleExoPlayerView;
SimpleExoPlayer player;

それから、次のようにアクティビティの onCreate メソッドで simpleExoPlayerView を初期化します。

simpleExoPlayerView = findViewById(R.id.simple_exoplayer_view);

そして onStart メソッドで、 次のように setupPlayer メソッドを呼び出します。

@Override
protected void onStart() {
    super.onStart();
    setupPlayer();
}

次のように setupPlayer メソッドも呼び出します。

void setupPlayer(){
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory =
            new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector =
            new DefaultTrackSelector(videoTrackSelectionFactory);

    //既定の構成でプレーヤーを初期化します
    player = ExoPlayerFactory.newSimpleInstance(this, trackSelector);

    // simpleExoPlayerView を割り当てます
    simpleExoPlayerView.setPlayer(player);

    // メディアデータが読み込む DataSource インスタンスを作ります。
    DataSource.Factory dataSourceFactory =
            new DefaultDataSourceFactory(this, Util.getUserAgent(this, "CloudinaryExoplayer"));

    // メディアデータを解析する抽出インスタンスを作ります。
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

    // これはメディアが再生される MediaSource を表します
    MediaSource videoSource = new ExtractorMediaSource(videoUri,
            dataSourceFactory, extractorsFactory, null, null);

    // ソースでプレーヤーを用意します。
    player.prepare(videoSource);
}

ここで、既定の構成で player を初期化し、それを SimpleExoPlayerView インスタンスに割り当てます。videoUriUri のタイプです。格納された全てのファイルには Uri があり、そのファイルを一意のアドレスにします。ビデオをリモート URL から表示するのであれば、次のように解析する必要があります。

Uri videoUri = Uri.parse("any_remote_url");

これが ExoPlayer の基本的な実装になります。Google では このライブラリで始める方法についての素晴らしいチュートリアル を提供しています。

Android ライブラリ — ネットワーク

最近のほとんど全てのモバイルアプリは、機能を実行するために何らかのネットワークコミュニケーションを必要とします。これまで、ネットワーク要求をしたければ、Async タスククラスを実行して HttpsUrlConnection を使ってデータをフェッチする必要がありました。しかし、これは、特に大量のデータを返す API を使うときは、あまり有効ではありません。

幸運なことに、スレッドやデバイスのリソースを適切に管理しながら、このプロセスを最適化する素晴らしいネットワーク ライブラリがあります。代替オプションの中で、Retrofit と Volley が際立ちます。この 2 つでは Retrofit の方が人気が高いので、これを見ていきましょう。

Retrofit

Retrofit は Square(Picasso をサポートする同じ会社)が開発・管理する Android / Java 用の タイプセーフ HTTP クライアントです。Retrofit は Android 開発では最もよく使われているネットワークライブラリです。Retrofit は注釈だけで要求本文の追加、エンドポイントの操作、ヘッダーの操作、クエリ パラメータの追加、要求メソッドの選択が簡単にできます。Retrofit はコンバータを使って、POJO の解析を処理します。

RETROFIT を使用する

Retrofit を使用するには、まず、次のように依存関係をアプリ build.gradleファイルに追加します。

implementation 'com.squareup.retrofit2:retrofit:2.3.0'

また、使用する予定のコンバーターの依存関係も挿入します。コンバーターは応答本文に対する Java オブジェクトのマッピングを処理します。コンバーターについての詳細は こちら をご覧ください。

implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'

上記の最初のコンバーター(converter-gson)はその名前のとおり、JSON フォーマットから/までマップします。ふたつめは String のようにプリミティブ データ型で処理したいときに使用します。ご希望のコンバーターをインポートした後、次のようにアクセスするエンドポイントを構成するインターフェイスを作成します。

public interface ApiService {
    @GET("/data")
    Call<ResponseClass> fetchData(@Body JsonObject jsonObject);
}

そのスニペットから、要求に対して JsonObject @Bodyを必要とするエンドポイント /data があります。また、要求の予想応答本文にマップされる ResponseClass もあります。ただし、クラスは簡潔にするため、ここでは省略されます。POJO に対して JSON オブジェクトをマップするには、JsonSchema2Pojo ライブラリを使用します。

利用可能なエンドポイントを定義した後、次のように Retrofit クライアントを作成します。

public class RetrofitClient {    
    static ApiService getService(){
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl("http://127.0.0.1:5000/")
                .addConverterFactory(GsonConverterFactory.create());

        Retrofit retrofit = builder
                .client(httpClient.build())
                .build();

        return retrofit.create(ApiService.class);
    }
}

Retrofit オブジェクトを構築するとき、必要な数のコンバーターを追加できます。これによってデータを解析するオプションが広がります。その後、次のように呼び出しでネットワーク要求をします。

RetrofitClient.getService().fetchData(jsonObject).enqueue(new Callback<ResponseClass>() {
    @Override
    public void onResponse(Call<ResponseClass> call, Response<ResponseClass> response) {

    }

    @Override
    public void onFailure(Call<ResponseClass> call, Throwable t) {

    }
});

jsonObject が要求パラメータを含む場合です。この要求は上記のコードスニペットで定義されたように http://127.0.0.1:5000/data エンドポイントに対して行われます。この最後のスニペットでご覧のように、Retrofit もコールバック メソッドを提供して要求の状況を提供します。

Android ライブラリ — 依存関係挿入

依存関係挿入 はオブジェクトがその依存関係を構成する必要がない場合の概念です。代わりに、依存関係は別のオブジェクトによってパスされます。この原理はクラスを実装から切り離すのに役立ちます。コードがゆったりと結合され、管理やテストが簡単になるので、エンジニアプラクティスの良い、注目に値するソフトウェアです。依存関係挿入のライブラリはたくさんありますが、Dagger2 が主力のようです。

Dagger2

Dagger2 は Java および Android 用の完全静的、コンパイル時間 依存関係挿入 のフレームワークです。これは Square が作成した以前の バージョン(Dagger1) のアップグレードで、現在は Google が管理しています。最新の Dagger バージョンには Android 用の Android 固有ヘルパーが含まれています。具体的には、新しいコードジェネレータを使用する自動生成のサブコンポーネントが含まれています。Dagger2 は非常に深く、適切に理解するには簡単な使用例以上のものが必要とされますが、とにかく見てみましょう。

DAGGER2 を使用する

いつものように、次のようにアプリモジュール build.gradle ファイルに依存関係を追加します。

implementation 'com.google.dagger:dagger:2.14.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'
// これを追加したので Android サポートライブラリを使用できます
implementation 'com.google.dagger:dagger-android-support:2.14.1'
annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1'

その後、アクティビティ ビルダー モジュールクラスを作成して Dagger が依存関係を必要とするそのアクティビティのサブコンポーネントを作成できるようにします。

@Module
public abstract class ActivityBindingModule {
    @ContributesAndroidInjector()
    abstract MainActivity mainActivity();
}  

任意ですが、アクティビティへの特定の依存関係でモジュールクラスを作成できます。それから、例えば次のように、そのモジュールを @ContributesAndroidInjector 注釈のコンストラクターに追加します。

@ContributesAndroidInjector(modules = {MainActivityModule.class} )
abstract MainActivity mainActivity();

また、1 つのアクティビティクラス以上に使用する依存関係を提供するためにモジュールクラスをもうひとつ作成できます。

Module クラスを @Module で注釈して、オブジェクトを提供する担当にします。オブジェクトは提供されているものと同じ戻り値の型があるメソッド(通常 @Provides または @Binds の注釈付き)を作成して提供されます。以下のサンプルのモジュールクラスはアプリに String を提供します。

  @Module
  public abstract class AppModule {
      @Provides
      static String providesString(){
          return "I love Auth0";
      }
  }

@Module を配置したら、抽象クラスまたはインターフェイスを作成します。この場合 AppComponent と名付けます。AppComponent には @Component の注釈付けをします。注釈はサポートライブラリからの AndroidSupportInjection クラスを含む、上記で作成したモジュールクラスに入れます。Dagger はクラスを生成してから、このインターフェイスを実装します。このクラスはパスしたモジュールから挿入されたインスタンスを提供します。この Component インターフェイスは次のように表示されます。

@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, AppModule.class, ActivityBindingModule.class})
public interface AppComponent extends AndroidInjector<AppController> {
    @Override
    void inject(App instance);

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);
        AppComponent build();
    }
}

AppController はアプリのアプリケーションクラスで、オブジェクトはアプリのライフサイクルで初期化されます。AppController は次のように表示されます。

public class App extends Application implements HasActivityInjector {
      @Inject
      DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;
      @Override
      public void onCreate() {
        super.onCreate();
        DaggerAppComponent.builder().application(this)
            .build().inject(this);
      }
      @Override
      public DispatchingAndroidInjector<Activity> activityInjector() {
        return activityDispatchingAndroidInjector;
      }
}

DispatchingAndroidInjector<Activity> のインスタンスを作成し、実装されたメソッドに返します。これは、アクティビティにメンバー挿入するためです。それから Component を構築し、Application クラスにそれを挿入します。

最後に、依存関係を使用するつもりのアクティビティで、HasSupportFragmentInjector を実装し、次のように @Inject 注釈を使って依存関係にアクセスします。

public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector {

    @Inject
    DispatchingAndroidInjector<Fragment> fragmentDispatchingAndroidInjector;

    @Inject
    String string;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        Log.d("TAG",string);
    }

    @Override
    public AndroidInjector<Fragment> supportFragmentInjector() {
        return fragmentDispatchingAndroidInjector;
    }
}

App クラスで同じようなことをしましたが、唯一の違いはここでは HasSupportFragmentInjector を実装しているので DispatchingAndroidInjector<T> には Fragment があります。この論理は、Application には Activities が含まれ、これらは Fragments を囲むということです。この後、AndroidInjection.inject(this)onCreate メソッドに呼び出します。

この簡単な例を使ってこのアプリを実行している方には、I love Auth0 がログに書き出されます。依存関係をクラスで初期化する代わりに、挿入できました。これが Dagger2 が提供する機能の一部です。詳細については、次の 2 つの記事を参照してください。

Android ライブラリ — ビューバインディング

ビューバインディング ライブラリはビューを変数に割り当て、アクティビティクラスのそれらにアクセスする場合、定型句コードを減らす必要があるときに出現します。このエリアのライブラリは限られています。基本的に、重要な点はButterKnife と Android データ バインディングの 2 つです。

Butterknife

ButterKnifeJake Wharton が開発したビューバインディング ライブラリです。Butterknife は ids をビューに割り当てるときに役立つライブラリで、過剰 findViewById を避けます。ドキュメントの「シャープさが無限に少ないだけで Butterknife は Dagger のよう」によると、ビューバインディングは依存関係挿入の形態として見ることができる、ということです。ButterKnife では、注釈は代わりに定型句コードを生成するために使用されます。

Butterknife を使用する

Butterknife を使用するには、依存関係をアプリモジュール build.gradle ファイルに次のように追加する必要があります。

implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

それから、アクティビティで、@BindView 注釈を使って次のように id をそのビューに割り当てます。

class MainActivity extends AppCompatActivity {
    @BindView(R.id.firstname) EditText firstName;

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
        ButterKnife.bind(this);
        // TODO ...
    }
}

上記のコード スニペットでは、bind メソッドを使って onCreate メソッドの ButterKnife を初期化したことに注意してください。代わりに、ButterKnifeFragment に使用したければ、次のように onCreateView メソッドでそれを初期化します。

View view = inflater.inflate(R.layout.sample_fragment, container, false);
ButterKnife.bind(this,view);

ButterKnife を使って OnClickListeners の作成を避けます。例えば、@OnClick 注釈とビューを一緒に使って、次のようにクリックリスナーをビューに追加します。

@OnClick(R.id.button)
void buttonClicked() {
  // TODO ...
}

ButterKnife についてのドキュメントは こちらから アクセスしてそのライブラリの機能について学ぶことができます。

Android データバインディング ライブラリ

Android データバインディング ライブラリ は Android Support Library に内蔵されています。Android Studio のバージョン 1.3 以降が必要です。ButterKnife とは異なりこのライブラリは注釈を使用しません。

データバインディング ライブラリを使用する

アプリモジュール build.gradle ファイルで次のようにデータバインディングと同期化が可能になります。

android {
    ....
    dataBinding {
        enabled = true
    }
}

その後、レイアウトファイルのルートタグを次のように layout に設定します。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </android.support.constraint.ConstraintLayout>

</layout>

それから、アクティビティ バインディング クラスがレイアウトの名前activity.main.xml を基に生成されます(ActivityMainBinding)。このクラスのインスタンスを使ってビューにアクセスします。他のユーティリティを処理するために生成された別のクラス DataBindingUtil もあります。

それから、アクティビティクラスでは次のようになります。

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.textview.setText("Hello world!");
    }
}

Android データバインディング ライブラリはその他たくさんの機能と共に、onClick リスナーの置換を提供します。これら機能については公式 ドキュメント をご覧ください。

ButterKnife と Android Databinding Library の 2 つのライブラリはビューにアクセスするために書くコードの量を大きく減らします。しかし、Android DataBinding ライブラリは ButterKnife と比較したとき、より簡単な設定、少ないコードで結果達成、より多くの機能などを提供するため、勝ち目があるようです。

Android ライブラリ — リアクティブプログラミング

リアクティブプログラミングは、データがコンポーネント(ソース)から別のコンポーネント(サブスクライバー)に生成されるパラダイムです。これによって非同期のタスクを効果的に処理できます。よって、リアクティブプログラミング ライブラリはデータをソースからサブスクライバーにパスするのに役立つライブラリです。Android 開発者にとって最も人気の高い代替オプションは RxJava2 と RxAndroid です。よって、これらを見ていきましょう。

RxJava2 & RxAndroid

RxJava はリアクティブプログラミング を実装させるライブラリですから、リアクティブアプリケーションを作ります。RxJava2 は RxJava の旧バージョンのアップデートです。RxJava2 には Observables、Observers、Schedulers があります。

Observables はデータソースで、ObserverSingleFlowableMaybeCompletable のさまざまなタイプがあります。これら各タイプには固有の使用ケースがあり、その詳細については こちら をご覧ください。

特に Flowable には バックプレッシャ サポートが付いています。バックプレッシャは ObserverObservable にシグナルを送るとき、後者が値を早く発行し過ぎることです。Observers はデータレシーバー(またはコンシューマ)で、Schedulers はスレッドの管理に役立ちます。

一方、RxAndroid は RxJava2 の拡張子です。メインスレッドでスケジュールする Scheduler のプロビジョニングまたは指定された Looper のような Android プラットフォームに特有の機能を提供します。

RXANDROID を使用する

RxAndroid を使用するには、次のようにアプリモジューラ build.gradle ファイルに依存関係を追加する必要があります。

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// RxAndroid リリースはとてもまれなので、バグ修正と最新機能には 
// RxJava の最新バージョンに明示的に依存することを推奨します。
compile 'io.reactivex.rxjava2:rxjava:2.1.7'

それから、CompositeDisposable のインスタンスをクラスに作成します。CompositeDisposable は次のように複数の破棄可能を保留できるコンテナーです。

disposables.add(
  Observable.just("Hello world!")
  // バックグラウンドスレッドで実行します
  .subscribeOn(Schedulers.io())
  // メインスレッドで通知を受けます
  .observeOn(AndroidSchedulers.mainThread())
  .subscribeWith(new DisposableObserver<String>() {
      @Override
      public void onComplete() {

      }

      @Override
      public void onError(Throwable e) {

      }

      @Override
      public void onNext(String value) {

      }
  })
);

上記のコードスニペットでは、disposables 変数に追加したものは 1 つの文字列を発行するデータソース、プロセスが行われるスレッド、オブザーバーが結果の通知を受けるスレッド、サブスクライバー/オブザーバーで成ります。DisposableObserver<String> はオブザーバーで、実装する 3 つのメソッドを提供します。ひとつめはデータが発行されたときに呼び出される onNext、ふたつめはエラーが発生したことを示す onError、みっつめは Observable がデータ発行を終了し、これ以上 onNext を呼び出さないことを示す onCompleted です。

それから、アクティビティがバックグラウンドにあるときに、次のようにリソースを消去してメモリリークを避けます。

    @Override
    protected void onPause() {
        super.onPause();
        disposables.clear();
    }

基本的ですが、興味深い Mindorks によるチュートリアルがありますので、RxJava2 についての詳細は こちら をご覧ください。

Android ライブラリ — テストする

ソフトウェアのテストは単に、バグを見つける目的で行われます。テストは長い間にわたって進化し、ソフトウェア開発プロセスの最終段階のひとつをとっても、はるかに超えるものです。実際、テストは最初に書き込みが行われる場合はコーディング段階の初期で採用され、それからソフトウェアの論理が実装されてテストが予期することのみをパスします。これは通常、テスト駆動開発 として参照されます。アプリケーションのテストを書き込むことはバグを素早く見つけたりアプリケーションの強化に役立つので良いプラクティスです。さまざまな長所のテストライブラリがたくさんあり、Android 開発で使用できます。そのうちの 4 つ、JUnit、Mockito、Robolectric、Espresso を見てみましょう。

JUnit

JUnit は単体テストに使用するフレームワークです。単体テストはテストのタイプで、ソースコードの個々の単体がテストされます。このフレームワークには assert メソッドのセットが含まれ、実際の結果に対して期待される結果をチェックします。JUnit は注釈を多用します。その例を少し挙げると、@Test(テストメソッドを識別する)、 @Before(テストが呼び出される前に呼び出されるべきメソッドを宣言する)、@After(テストの後に呼び出されるべきメソッドを宣言する)があります。

JUNIT を使用する

まず、次のようにアプリモジュール build.gradle ファイルに依存関係を追加します。

testImplementation 'junit:junit:4.12'

それから、サンプルのテストクラスは次のように表示されます。

public class ExampleUnitTest {
    @Test
    public void additionIsCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

ここでは、2 と 2 を足すと 4 になることを確認します。JUnit テストは通常、JVM で実行し、デバイスやエミュレーターを必要としないので、 早くできます。JUnit テストの詳細については こちら をご覧ください。

Mockito

ほとんどの場合、テストを書き込むクラスは他のクラスに依存します。この目的だけのためにこれらクラスを構成するのは荒ただしい作業になります。このような場合に Mockito を使用します。これはモッキングフレームワークで、モック(フェイク)オブジェクトを作成・構成するのに役立ちます。通常、JUnit と一緒に使用します。

Mockito を使用する

まず、JCenter レポジトリ、jcenter() がプロジェクト build.gradle ファイルにあるかを確認します。次に、その依存関係をアプリモジュール build.gradle ファイルに追加して次のように同期します。

testCompile 'junit:junit:4.12'
// 単体テストの ために Mockito を使用したい ならば 必須です
testCompile 'org.mockito:mockito-core:2.13.0'
// Android テストの ために Mockito を使用したい ならば 必須です
androidTestCompile 'org.mockito:mockito-android:2.13.0'

それから、次のように Mockito を使用します。

@Test
public void mockitoTest throws Exception {
    List mockedList = mock(List.class);

    // モックオブジェクトを使用すること
    mockedList.add("one");
    mockedList.clear();

    // 検証
    verify(mockedList).add("one");
    verify(mockedList).clear();
}

ここで、リストをモックし、それにデータを追加し、それを消去します。それから、これらアクションが実施されたことを検証します。Mockito を使ったテストについての詳細は、公式 ドキュメント をご覧ください。

Robolectric

Robolectric はもうひとつの単体テストライブラリです。JUnit との違いは、この Robolectric は Android 開発者に役立つように作られたことです。Robolectric はビューのインフレ、リソース読み込みなどその他多数を処理します。これにより、テストは Espresso などでデバイスを起動せずに、Android フレームワーク依存関係がある実際のデバイスでできるほとんどのことができます。ある意味、Robolectric はテストのために Android SDK をシュミレートします。Robolectric では、Mockito のような追加のモッキングフレームワークが必要ありません。

ROBOLECTRIC を使用する

Robolectric を使用するには、次のようにアプリ build.gradle ファイルに依存関係を追加します。

testCompile "org.robolectric:robolectric:3.6.1"

それから、次のようにサンプルのテストクラスを作成します。

@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class MyActivityTest {

  @Test
  public void checkActivityNotNull() throws Exception {
    Activity activity = Robolectric.setupActivity(MyActivity.class);
    assertNotNull( activity );
  }
}

これは非常に基本的なテストで、アクティビティをセットアップし、Null でないことをチェックします。Robolectric を使ったテストについての詳細は こちら からご覧ください。

Espresso

Espresso はテストフレームワークで、Android Testing Support Library の一部です。このテストフレームワークで、Android アプリ用のユーザーインターフェイス テストを作成できます。つまり、Espresso で TextView のテキストが別のテキストに一致するかをチェックできるテストを書くことができます。Espresso テストは実際のデバイスとエミュレーターの両方で実行でき、まるで実際のユーザーがアプリを使っているかのように動作します。

ESPRESSO を使用する

まず、次のようにアプリモジュール build.gradle ファイルにこれら依存関係を追加します。

androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
androidTestCompile 'com.android.support.test:runner:1.0.1'

それから、同じ gradle ファイルに、インストルメンテーションランナーを設定します。その後に、次のような Gradle ファイルの同期化を忘れないようにしましょう。

defaultConfig {
    applicationId "com.my.awesome.app"
    minSdkVersion 15
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"

    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

それから、次のようなテストファイルを(例: EspressoSampleTest)を作成できます。

@RunWith(AndroidJUnit4.class)
public class EspressoSampleTest {
    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule(MainActivity.class);

    @Test
    public void isHelloWorldDisplayed() {
        onView(withText("Hello world!"))
          .check(matches(isDisplayed()));
    }
}

このテストクラスは MainActivity が開いたときに「世界の皆さん、こんにちは」のメッセージが表示されるかを確認します。

さまざまなテストライブラリの調査から、JUnit はその他のライブラリと共に作動するので、何とも競合しないと推測されます。Espresso はユーザーインターフェイス テストに良いプラットフォームを提供します。Mockito と Robolectric の両方には同じような機能がありますが、Robolectric は少ないコードでテストを達成します。Robolectric はビューをテストするなど、多くの機能も提供します。Robolectric には Google エンジニアのサポートがあるという有利な点もあります。

Android ライブラリ — データベースヘルパー

オフラインデータの永続性はユーザーエクスペリエンスを高めるのに非常に重要です。通常、アプリを次回起動するのに必要な重要情報を保存するアプリケーション、またはインターネット接続が使えないときにデータを使えるようにするアプリケーションが必要です。データを保存することはキーと値を組み合わせるよりももっと複雑ですから、このタスクを Android に簡単に保存するために多数のライブラリが作成されました。本章では、Room のような素晴らしい永続化ライブラリを見て行きます。

Room

Room は永続化ライブラリで、Android Architecture Components の一部です。Room は最小の定型句コードに一貫するローカルデータを提供します。SQLite 上に抽象化レイヤーを提供するので、アプリのデータベースと取り組むのが簡単になります。このライブラリにはコンパイル時間で SQL クエリの検証、メインスレッド上のデータベースクエリの拒否(データベースの初期化中に明示しているときは除く)、実装ベストプラクティスの提示などたくさんの長所があります。

Room はデータベース、DAO (Data Access Object)、エンティティの 3 つのメインコンポーネントでできています。それぞれはライブラリを機能させるために相関性があります。Entity クラスはデータベーステーブルを表し、@Entity の注釈が必要です。クラスの変数はテーブルにある列を表します。DAO はデータベースにアクセスするために使用するメソッドを含むインターフェイスです。Room はインターフェイスを使用し、次のようにユーザーのための実装クラスを生成します。

基本的な DAO 操作に固有の注釈には@Insert、@Update@Delete@Query の 4 つがあります。それから、データベースクラスがあります。これは @Database の注釈が付いた抽象クラスで、RoomDatabase を拡張します。このクラスは使用するエンティティと DAO のリストを定義します。

ROOM を使用する

Room を使用するには、まず Google Maven レポジトリをプロジェクト build.gradle ファイルに追加します。前回の Android プロジェクトは次で事前に構成されています。

allprojects {
    repositories {
        // ... その他リポジトリ
        google()
    }
}

それから、Room 依存関係を次のようにアプリモジュール build.gradle ファイルに追加します。

implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

次に、Entity クラスを作成します。いつものように、かなりシンプルなものを使います。そして、idname の 2 つの列があります。id 列は主キーで、追加した全ての行が固有になるように自動生成されます。

@Entity(tableName = Person.TABLE_NAME)
public class Person {
    public static final String TABLE_NAME = "person";
    String name;
    @PrimaryKey(autoGenerate = true)
    public int id;
}

テーブルはずっと小文字で名付けることがベストプラクティスです。Java クラスに名付けるときとは同じ慣習ではないので、テーブルにはカスタム名を使用できます。通常、Room はテーブル名としてクラス名を使用します。その後、DAO を作成します。DAO はデータベース自体にインターフェイスを提供し、データのクエリと保存を処理します。次に、次のようにデータベース操作に使用するメソッドを含む DAO を作成します。

@Dao
public interface PersonDao {
    // データベースに個人を追加します
    @Insert
    void insert(Person person);

    // データベースから個人を削除します
    @Delete
    void delete(Person person);

    // データベースの個人全てを取得します
    @Query("SELECT * FROM "+Person.TABLE_NAME)
    List<Person> getAllPeople();
}

インターフェイスはさまざまなメソッドに配置された注釈で一目瞭然です。その後、データベースクラスを作成します。これは、次のようにデータベースを管理し、インスタンスを DAO に提供することが担当の抽象クラスです。

@Database(entities = {Person.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract PersonDao getPersonDao();
}

これらクラスを配置したら、データベースのインスタンスを取得し、クエリを作り始めます。アプリのライフサイクルでデータベースのインスタンスを 1 つだけ作ることが推奨されています。これを次のように Application クラスでできます。

public class App extends Application {
    private static AppDatabase appDatabase;

    @Override
    public void onCreate() {
        super.onCreate();

        // アプリのライフサイクルで db を一度初期化します
        appDatabase =  Room.databaseBuilder(
            getApplicationContext(),
            AppDatabase.class,
            "person.db"
        ).build();
    }

    public static AppDatabase provideDb(){
        return appDatabase;
    }
}

それから、データベースインスタンスにアクセスして、データをデータベースに挿入します。これは次のように DAO クラスの insert メソッドを呼び出して実行します。

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override
    public void run() {
        // データベースに挿入します
        Person person = new Person();
        person.name= "Idorenyin Obong"
        App.provideDb().getPersonDao().insert(person);
    }
});

ここで、Person のインスタンスを作成し、データベースに挿入しました。前述したように、id は自動的に作成されるので、名前だけを割り当てました。バックグラウンドでクエリを実行する新しいスレッドを作成したことにもご注意ください。データベースでその他の演算操作を実施する上記のパターンを同様に採用します。

Google は、ユーザーがこのライブラリで始めることができるように ナイスチュートリアル を提供しています。

Android ライブラリ - カスタムフォント

ほとんど全ての Android 開発者はアプリの外観に一生懸命です。ときには、アプリが全デバイスに同じ感覚を与えることができるように、固有のフォントを選ぶために一層の努力を要することがあります。このような状況で、アプリの全てのテキストにカスタムフォントを使うことができるライブラリがあります。

Calligraphy

Calligraphy は最も人気が高いカスタムフォント ライブラリのひとつで、使い方はとても簡単です。このライブラリで、アプリケーション全体で同じフォントを使ったり個々のテキストにフォントを定めたり簡単にできます。

Calligraphy を使用する

いつものように、次のようにアプリモジュール build.gradle ファイルに依存関係を追加し、それを同期化します。

implementation 'uk.co.chrisjenx:calligraphy:2.3.0'

それから、assets フォルダを作成し、そこにカスタムフォントを挿入します。Android Studio のプロジェクトディレクトリにあるアプリケーションのルート フォルダを右クリックし、[New]、[Folder] を選択し、それから [Assets Folder] を選択します。これで、アセットフォルダが生成されます。その後、そのライブラリを初期化し、次のように Application クラスに既定のフォントを設定します。

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                .setDefaultFontPath("red-velvet.ttf")
                .setFontAttrId(R.attr.fontPath)
                .build()
        );
    }
}

最後に、次のように各アクティビティの attachBaseContext メソッドを上書きします。

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

これで完成です!これで、Red Velvet フォントがこのアプリの既定のフォントになりました。次のように単一のテキストに特定のフォントを適用することもできます。

<TextView
    android:text="@string/hello_world"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    fontPath="fonts/red-velvet.ttf"/>

カスタムフォントとサポートライブラリ

Android Support Library のお陰で、バージョン 26以上からアプリの依存関係を増やさずにカスタムフォントを使用できます。これはどっちみち build.gradle ファイルで appcompat 依存関係を見つけるのでこのようになります。これは新しい Android プロジェクトを作成するときに自動的に追加されます。

implementation 'com.android.support:appcompat-v7:26.1.0'

SUPPORT LIBRARY でカスタムフォントを使用する

まず、fonts リソースフォルダを作成します。これは res フォルダを右クリックしてから、[New → Android リソース] ディレクトリを選択します。その後、リソースタイプとしてのフォントを選択し、[OK] を選択します。それから font リソースディレクトリ(例 redvelvet)に希望するフォントファイルを追加します。

カスタムフォントを次のように直接 XML レイアウトに適用します。

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/redvelvet"/>

さらに、新しいフォントファミリを作成できます。フォントファミリはスタイルや太さの詳細を合わせたフォントファイルのセットです。そのフォントソースフォルダを右クリックし、[New] をクリックし、それから [New Font Resource File] をクリックして名前を挿入し、[OK] を選択します。サンプルのフォントファミリは次のようなものがあります。

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">
    <font
        app:font="@font/redvelvet"
        app:fontStyle="normal"
        app:fontWeight="400" />
</font-family>

フォントを XML レイアウトに適用すると、使用されたテキストスタイルを基にシステムが正しいフォントをピックします。フォントを XML レイアウトに適用することはさておき、それらをプログラムや複数のフォームで適用することも可能ですので、公式 ドキュメント でご覧ください。Support Library でカスタムフォントを使用することについての素晴らしいリソースは こちら をご覧ください。

ジョブのスケジューリング

往々にして Android アプリケーションはユーザーのインタラクションから操作する必要があることがあります。このために、アプリのパフォーマンスとデバイスを全般に最適化するためにタスクを非同期、かつインテリジェントに処理する必要があります。これで、バックグラウンドで処理するタスクが均等に呼び出されます。

Android にはバックグラウンドタスクをスケジューリングする独自の API、JobScheduler があり、API 21 (Android 5.0) 以降をサポートするときのみ使用できるという短所があります。

このカテゴリの 2 つの共通オプションは Evernote による Android ジョブライブラリ と Firebase による Firebase Jobdispatcher があります。

Firebase Jobdispatcher には Google Play 開発者サービスが必要というもうひとつの代償がありますが、ずっと前の API 9 (Android 2.3) まで互換性があります。Android ジョブは Android の JobScheduler と Firebase Jobdispatcher の取り組みを結合して安定したジョブスケジューリングライブラリを提供します。広く普及されているのも不思議ではありません。

Android ジョブ

Android ジョブ はバックグラウンドでジョブを処理するために使用する Android ライブラリです。Android のバージョンによって JobSchedulerGcmNetworkManager、または larmManager のどれかが使用されます。これが、このライブラリが人々の心を引き付ける理由です。ひとつのコードベース内で別の API を使って、使用するスケジューリング API を知るために API バージョンを確認する代わりに、Android ジョブはコードサイズの他にストレスも減らして実行してくれます。このライブラリは API 14 (Android 4.0) 以降が必要です。

Android ジョブを使用する

Android ジョブを使用するには、次のようにアプリモジュール build.gradle ファイルに依存関係を追加し、それを同期化します。

compile 'com.evernote:android-job:1.2.1'

それから、次のように Application クラスの JobManager を初期化します。

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        JobManager.create(this).addJobCreator(new SampleJobCreator());
    }
}

この Application クラスはアプリケーションサイクルでオブジェクトを一度だけ初期化するために使用されます。SampleJobCreator はジョブの一意タグを基にした Job のインスタンスを返すクラスです。SampleJobCreator は次のように表示されます。

public class SampleJobCreator implements JobCreator {
    @Override
    @Nullable
    public Job create(@NonNull String tag) {
        switch (tag) {
            case FirstJob.TAG:
                return new FirstJob();
            default:
                return null;
        }
    }
}

最後に、FirstJob と名付けられた Job クラスは次のように表示されます。

public class FirstJob extends Job {
    public static final String TAG = "first_job_tag";
    @Override
    @NonNull
    protected Result onRunJob(@NonNull Params params) {
        // ここでジョブを実行します
        return Result.SUCCESS;
    }

    public static void scheduleJob(long timeJobShouldStart) {
        new JobRequest.Builder(ReviewStayJob.TAG)
                .setExact(timeJobShouldStart)
                .build()
                .schedule();
    }
}

上記のコードスニペットでは、onRunJob メソッドで何をするかを Job に伝えました。それから、FirstJob.scheduleJob(timeinMills)timeInMillis がデータ型 long の場合)を呼び出してジョブをスケジュールします。GitHub repo はデバイスが充電しているときにジョブを実行するように伝えるなど、もっと複雑なスケジューリングのオプションを提供します。

「Android ライブラリに関する素晴らしい記事を読みました。」

補足:Android アプリを Auth0 でセキュアにする

アプリケーションを Auth0 でセキュアにすることは非常に簡単で、たくさんの素晴らしい機能を提供します。Auth0 を使うと、数行のコード行を書くだけで、強固なID 管理ソリューションシングル サインオンソーシャル ID プロバイダー(Facebook、GitHub、Twitter など)のサポート、およびエンタープライズ ID プロバイダー(Active Directory、LDAP、SAML、カスタムなど)のサポートを得ることができます。

以下のセクションでは、Android アプリをセキュアにする Auth0 を使用する方法を学んでいきます。ご覧のように、そのプロセスはシンプルで素早くできます。

依存関係

Android アプリを Auth0 でセキュアにするには、Auth0.Android ライブラリをインポートするだけです。このライブラリはツールキットで、基本的な多数の Auth0 API 機能と素晴らしい方法で通信することができます。

このライブラリをインポートするには、build.gradle ファイルに次の依存関係を含みます。

dependencies {
    compile 'com.auth0.android:auth0:1.12.0'
}

その後、アプリの AndroidManifest.xml ファイルを開き、次のアクセス許可を追加します。

<uses-permission android:name="android.permission.INTERNET" />

クライアントを作成する

ライブラリをインポートしてアクセス許可を追加した後、新しいクライアントアプリケーションを Auth0 ダッシュボードに作成します。ところで、Auth0 アカウントをお持ちでない方は、無料アカウントを作成する でアカウントを作成されることをお勧めします。

Auth0 ダッシュボードで、クライアント に移動し、クライアントを作成する ボタンをクリックします。表示のフォームで、クライアントの名前を定義し、その ネイティブ タイプを選択します。その後、作成 ボタンを押します。これで、次のようなスクリーンが表示されます。

Android application on Auth0's dashboard

このスクリーンで、コールバック URL を構成します。これは、Auth0 がユーザーを認証した後にリダイレクトするアプリケーションの URL です。

クライアント 設定 ページの 許可されたコールバック URL フィールドにあるアプリのコールバック URL をホワイトリストします。コールバック URL を設定しなければ、ユーザーがログインしたときに不一致のエラーが表示されます。

demo://bkrebs.auth0.com/android/OUR_APP_PACKAGE_NAME/callback

OUR_APP_PACKAGE_NAME とアプリケーションのパッケージ名を置換することを忘れないようにしましょう。この名前は app/build.gradle ファイルの applicationId 属性にあります。

資格情報を設定する

アプリケーションは Auth0 と通信するために、クライアントの詳細情報が必要です。この詳細情報は Auth0 ダッシュボード にあるクライアントの 設定 セクションにあります。

次の情報が必要です。

  • クライアント ID
  • ドメイン

これらの値は将来、変更する必要があるかもしれないので、ハードコードしないことをお勧めします。代わりに、値を定義するときは @string/com_auth0_domain のような文字列リソースを使いましょう。

res/values/strings.xml ファイルを次のように編集しましょう。

<resources>
    <string name="com_auth0_client_id">2qu4Cxt4h2x9In7Cj0s7Zg5FxhKpjooK</string>
    <string name="com_auth0_domain">bkrebs.auth0.com</string>
</resources>

これらの値はクライアントの 設定 セクションにある値と置換します。

Android ログイン

ログイン機能をアプリに実装するには、SDK が必要とするマニフェスト プレースホルダーを追加します。これらプレースホルダーは前に構成された認証コールバック URL をキャプチャする intent-filter を定義するために内部で使用します。

マニフェスト プレースホルダーを追加するには、次の行を追加しましょう。

apply plugin: 'com.android.application'
android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.auth0.samples"
        minSdkVersion 15
        targetSdkVersion 25
        //...

        //---> Add the next line
        manifestPlaceholders = [auth0Domain: "@string/com_auth0_domain", auth0Scheme: "demo"]
        //<---
    }
}

その後、Android Studio 内で Gradle ファイルでプロジェクトを同期する を実行するか、コマンドラインから ./gradlew clean assembleDebug を実行します。

認証プロセスを開始する

Auth0 ログインページ は認証をアプリケーションに設定する最も簡単な方法です。最高のエクスペリエンス、最高のセキュリティ、完全な機能配列を得るには Auth0 ログインページをご使用されることをお勧めします。

では、認証プロセスを始めるためにメッソドを実装します。このメソッド login を呼び出し、それを MainActivity クラスに追加しましょう。

private void login() {
    Auth0 auth0 = new Auth0(this);
    auth0.setOIDCConformant(true);
    WebAuthProvider.init(auth0)
                  .withScheme("demo")
                  .withAudience(String.format("https://%s/userinfo", getString(R.string.com_auth0_domain)))
                  .start(MainActivity.this, new AuthCallback() {
                      @Override
                      public void onFailure(@NonNull Dialog dialog) {
                        // エラー ダイアログをユーザーに表示します
                      }

                      @Override
                      public void onFailure(AuthenticationException exception) {
                        // エラーをユーザーに表示します
                      }

                      @Override
                      public void onSuccess(@NonNull Credentials credentials) {
                          // 資格情報を保存します
                          // メインアクティビティに移動します
                      }
                });
}

ご覧のように、ユーザーの資格情報を保留するために Auth0 クラスの新しいインスタンスを作成しました。次の文字列リソースを追加したら、Android Context を受信するコンストラクターを使用できます。

  • string.com_auth0_client_id
  • string.com_auth0_domain

リソースのハードコードを希望する場合は、両方の文字列を受信するコンストラクターを使用できます。それから、Auth0 ダッシュボード のクライアントで有効にした接続で認証する WebAuthProvider クラスを使用します。

WebAuthProvider#start 機能を呼び出したら、ブラウザーを起動して Auth0 ログインページを表示します。ユーザー認証が終了したら、コールバック URL が呼び出されます。コールバック URL には認証プロセスの最終結果が含まれています。

結果をキャプチャする

認証の後、ブラウザーは認証結果と共にユーザーをアプリケーションにリダイレクトします。SDK はその結果をキャプチャして、分析します。

Auth0 ドメインとスキーム値でマニフェスト プレースホルダーを定義しましたので、アクティビティに固有の intent-filter を宣言する必要はありません。

AndroidManifest.xml ファイルは次のように表示されます。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.auth0.samples">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity android:name="com.auth0.samples.MainActivity">
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
        </activity>
    </application>
</manifest>

これだけです。これで、Auth0 で Android アプリケーションをセキュアにしました。これら詳細については、公式ドキュメント を参照してください。ここで セッションの処理方法ユーザープロファイルのフェッチ などのトピックを学ぶことができます。

まとめ

Android を開発しながら、ライブラリが、さまざまな機能を実行するために書かれた定型句コードの量をどのようにして大きく減らすかを学んできました。また、これらライブラリをほとんどのケースで使用する方法についても学びました。利用可能なライブラリの中で最高のライブラリについて知ることは、アプリの品質改善に役立ち、少ない時間で多くを作成できます。ですから、これらライブラリについて知り、使用することは有利な状況につながることは間違いありません。