Android: Dagger2でDIをする. u2020から読み解く編 Part2

概要

この記事では, JakeWhartonさんのu2020から, AndroidでDagger2を使うときの実践的な方法を紹介します. u2020はDagger1を使っていますが, Dagger2においても同様に使えるテクニックなので, u2020をベースにして説明します.

DI, Dagger2の基本について知りたい方は, Part1を見て下さい.

目次

debugとproductionでModuleを切り替える

gradleは, productFlavorsを設定することで, ソースコード, ビルド設定を切り替えることが出来ます. u2020では, production, internalのflavorがあります. そして, u2020はflavorの種類によって, DIする対象を切り替えています. production用のComponentとdebug用のComponentを作成することでそれを実現しています. 具体的には,

それぞれModuleを定義し, それをApplicationクラスから読み込むようにしています. これで, flavorごとにinjectするインスタンスを切り替えることが出来ます.

こうすると何が嬉しいんでしょうか? 例えば以下のことが可能になります.

以下では, より細かく説明していきます.

Debug専用のViewを作る

u2020では, Debug専用のView DebugAppContainerがあります. Debug専用のView はこんな感じです. Debugビルドの時は, このContainerをinjectしています.

DebugAppContainerは簡単にいえば, DrawerLayoutを1つ実装し, その中に「データをモックに変更する」, 「social機能を有効にする」などを設定出来るViewをおいています.

Mockモードの定義

u2020ではMockモードがあり, Mockデータを表示機能があります.

public final class DebugDataModule {
  ...
  ...

  @Provides @Singleton @ApiEndpoint
  StringPreference provideEndpointPreference(SharedPreferences preferences) {
    return new StringPreference(preferences, "debug_endpoint", ApiEndpoints.MOCK_MODE.url);
  }

  @Provides @Singleton @IsMockMode boolean provideIsMockMode(@ApiEndpoint StringPreference endpoint) {
    return ApiEndpoints.isMockMode(endpoint.get());
  }
}

上記のコードを見て分かる通り, デバッグビルドの時はMockモードが有効になります. デバッグ時にサーバがなくて困る時がありますが, u2020では, assets/内にデバッグ用のモックデータを入れておくことで, サーバ問題を解決しています. retrofitのMockRestAdapterを組み合わせ, mockからデータを取得しています.

activityのlifecycleのログを取る

Applicationクラスには, registerActivityLifecycleCallbacksメソッドがあり, このメソッドにActivityLifecycleCallbacksインターフェースの実装を登録することで, アプリ内で動いているActivityのライフサイクルのタイミング(onStart, onResume, …)でイベントを受け取ることが出来ます. ActivityLifecycleCallbackssインターフェースの定義は以下になります.

public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
public void onActivityStarted(Activity activity) {}
public void onActivityResumed(Activity activity) {}
public void onActivityPaused(Activity activity) {}
public void onActivityStopped(Activity activity) {}
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
public void onActivityDestroyed(Activity activity) {}

u2020では, SocketActivityHierarchyServerクラスをデバッグ, Activityが正しく振舞っているかを確認しています.

一元的にActivityのlifecycleログを取れるので, デバッグ時にはとても有効な機能だと思います.(u2020を見るまでは存在を知らなかった…)

まとめ

u2020はDagger以外にもノウハウが多くあり, 非常に勉強になりました. 正直10%くらいしか理解できていないので, 次はu2020全体にフォーカスを当てた記事を書くので楽しみに待っていて下さい.