- Android で Dagger を使う(その1)
- Android で Dagger を使う(その2 : subcomponent)
- Android で Dagger を使う(その3 : Android Support)
基本的に https://google.github.io/dagger/android.html に書かれている内容です。詳しくは原文を参照してください。
Activity や Fragment のインスタンスは Android フレームーワークによって生成されるため、ライフサイクルメソッドで inject する処理を明示的に行う必要があります。
- public class MainActivity extends Activity {
- @Inject
- GithubService service;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- ((MyApplication) getApplication())
- .getAppComponent()
- ...
- .inject(this);
- setContentView(R.layout.activity_main);
- }
- }
- (各 Activity や Fragment でこの処理を書くためコピー&ペーストされることになるだろう。)コピー&ペーストされたコードはのちのちリファクタリングするのが大変になる。多くの開発者がコピー&ペーストするようになってしまったら、実際に何をしているのか知っているのは一部の人だけになるだろう。
- より本質的な話をすると、この場合 inject をリクエストしている型(つまり MainActivity)がその injector について知っている必要がある。実際の型ではなく interface を通して inject されるとしても、「どのように inject されるのかを知っているべきではない」という dependency injection の原則を破ってしまっている。
この問題に対応するために、android 用のライブラリが別途用意されています。
- dependencies {
- compile('com.google.dagger:dagger-android:2.11') {
- exclude group: 'com.google.code.findbugs', module: 'jsr305'
- }
- compile('com.google.dagger:dagger-android-support:2.11') {
- exclude group: 'com.google.code.findbugs', module: 'jsr305'
- }
- annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
- }
1. AndroidInjectionModule の追加
AndroidInjectionModule を application component に追加します。- @Component(modules = AndroidInjectionModule.class)
- interface AppComponent {
- ...
- }
2.A @ContributesAndroidInjector を使わない方法
AndroidInjector を継承した Subcomponent を定義します。- @Subcomponent(modules = ...)
- public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {
- @Subcomponent.Builder
- public abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
- }
- @Module(subcomponents = MainActivitySubcomponent.class)
- abstract class MainActivityModule {
- @Binds
- @IntoMap
- @ActivityKey(MainActivity.class)
- abstract AndroidInjector.Factory<? extends Activity>
- bindMainActivityInjectorFactory(MainActivitySubcomponent.Builder builder);
- }
- @Component(modules = {AndroidInjectionModule.class, MainActivityModule.class})
- interface AppComponent {
- ...
- }
2.B @ContributesAndroidInjector を使う方法
2.A の subcompoennt およびその builder が他のメソッドや supertype を必要としないなら @ContributesAndroidInjector を使って生成させることができます。- @Module
- abstract class ActivityModule {
- @ContributesAndroidInjector(modules = ...)
- abstract MainActivity contributeMainActivityInjector();
- }
定義した module を application component に追加します。
- @Component(modules = {AndroidInjectionModule.class, ActivityModule.class})
- interface AppComponent {
- ...
- }
3. Application に HasActivityInjector を実装
Application に HasActivityInjector を実装し、inject した DispatchingAndroidInjector<Activity> を返すようにします。- public class MyApplication extends Application implements HasActivityInjector {
- @Inject
- DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
- @Override
- public void onCreate() {
- super.onCreate();
- DaggerAppComponent.create()
- .inject(this);
- }
- @Override
- public AndroidInjector<Activity> activityInjector() {
- return dispatchingActivityInjector;
- }
- }
- @Component(modules = {...})
- @Singleton
- public interface AppComponent {
- void inject(MyApplication myApplication);
- ...
- }
4. AndroidInjection.inject(this)
Activity の onCreate で super.onCreate() より前に AndroidInjection.inject(this) を呼ぶようにします。- public class MainActivity extends Activity {
- @Inject
- GithubService service;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- AndroidInjection.inject(this)
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- }
Base クラス
いくつかベースクラスが用意されています。dagger.android.DaggerXX クラスです。例えば DaggerApplication を使うと次のようになります。
AppComponent は AndroidInjector<MyApplication> を継承するようにし、MyApplication は DaggerApplication を継承するようにします。
- @Component(modules = {...})
- @Singleton
- public interface AppComponent extends AndroidInjector<MyApplication> {
- }
- public class MyApplication extends DaggerApplication {
- @Override
- public void onCreate() {
- super.onCreate();
- }
- @Override
- protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
- return DaggerAppComponent.create();
- }
- }
0 件のコメント:
コメントを投稿