5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Dagger2.1xの導入サンプル

Last updated at Posted at 2018-02-06

きっかけ

  • UIテストを書くときに、プロダクトのコードを変更せずにスタブを使ってテストしたい。

  • Daggerでオブジェクトの注入をして実現する。

  • 導入して綺麗に書けたと思うのでDagger2を導入したサンプルコード記述します。(UIテストへのDaggerの導入については別の記事に投稿する予定です)

環境

  • Android Studio3.0.1
  • dagger2
  • Java (KotlinのDIはDagger以外もあって悩ましそう)

参考にした記事

  • New Android Injector with Dagger 2 — part 1
  • 上や他の記事をみながら、サンプルアプリを動かして記事を見直して動きを把握しました。アノテーションは動きがわかりづらいです。役割や動きを把握までけっこう時間かかりました。:laughing:

サンプルアプリ

導入の進め方

いくつかクラスが必要ですので1つずつ作成していきます。動きを確認できる最低限のコードを用意します。

app/build.gradleに設定を記述する

dependencies {
    def daggerVersion = "2.14.1"
    compile "com.google.dagger:dagger-android:$daggerVersion"
    compile "com.google.dagger:dagger-android-support:$daggerVersion"
    annotationProcessor "com.google.dagger:dagger-android-processor:$daggerVersion"
    annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
}

dagger関連のクラスをbuild.gradleに記述します。公式にはdagger-compilerの記述がなかったのですが
こちらも必要でした。

カスタムApplicationクラスの作成

MainApplication.java
public class MainApplication extends Application implements HasActivityInjector, HasFragmentInjector {

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
    @Inject
    DispatchingAndroidInjector<Fragment> dispatchingFragmentInjector;


    @Override
    public void onCreate() {
        super.onCreate();
        DaggerAppComponent.builder().application(this).build().inject(this);
    }

    @Override
    public DispatchingAndroidInjector<Activity> activityInjector() {
        return dispatchingActivityInjector;
    }

    @Override
    public DispatchingAndroidInjector<Fragment> fragmentInjector() {
        return dispatchingFragmentInjector;
    }
}

クラスを作成した段階ではDaggerAppComponentを参照できないですが、後から解決されるのでこのまま進めます。
(HasFragmentInjectorはこのサンプルではFragment使っていないので必要なさそうです。)

AppComponentの記述

AppComponent.java
@Singleton
@Component(modules = {
        AndroidInjectionModule.class,
        AppModule.class,
        ActivityBuilder.class})
public interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(MainApplication application);
}

DaggerAppComponentの雛形になるクラス

AppModuleの記述

AppModule.java
@Module
class AppModule {

    @Singleton
    @Provides
    Context provideContext(Application application) {
        return application.getApplicationContext();
    }
}

アプリ全体で使いまわしたいオブジェクトを提供するようにします。
今回はContextが対象となりますが、APIクライアントのrepositoryなどを記述していくと思います。

ActivityBuilderの記述

ActivityBuilder.java
@Module
public abstract class ActivityBuilder {
    @ContributesAndroidInjector(modules = MainActivityModule.class)
    abstract MainActivity bindmainActivity();
}

オブジェクトをInjectするActivityをここで記述します。

MainActivityModuleの記述

MainActivityModule.java
@Module
public class MainActivityModule {
//    @Provides
//    HogeRepository provideRepository(MainActivity mainActivity) {
//        return new HogeRepository(mainActivity);
//    }
}

このサンプルではAppModuleに記述したContextを利用するだけなので、ここは何も記述していません。対象のActivityでInjectが必要ならコメントアウトの記述を参考にしてください。

MainActivityの記述

MainActivity.java
public class MainActivity extends AppCompatActivity {

    @Inject
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(context, "message", Toast.LENGTH_LONG).show();
    }
}

オブジェクトをInjectするクラスです。Contextを利用してToastを表示しています。
Toastが表示されるでしょうか。

終わりに

Daggerを使ったDIを試しました。以前のDaggerと比べてActivityに記載するコードが少なくスッキリしています。
アプリ設計でDIを使ってレイヤー間を疎結合にできるので、これから使っていきたいと思います。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?