Dagger2: 2.23に入ったHasAndroidInjectorについて

Dagger 2.23に新しく、HasAndroidInjectorインターフェースが入りました。 これは、従来のHasActivityInjectorHasFragmentInjectorなどを置き換えるために作られました。

この記事では、どのように置き換えるかを説明していきたいと思います。

また、DaggerApplicationDaggerActivityなどの基底クラスは使っていないものとします。

置き換えていく

AppComponent

AndroidSupportInjectionModuleを使っているなら、AndroidInjectionModuleに置き換えます。 今後は、AndroidSupportInjectionModuleを使う必要はありません。

@Singleton
@dagger.Component(
  modules = [
    AndroidInjectionModule::class, // AndroidInjectionModuleを使う
    ...
  ]
)
interface AppComponent ...

Application

Applicationで実装している、HasActivityInjector、HasServiceInjectorなどのHasxxxInjectorをHasAndroidInjectorに置き換えます。

class App : Application(),
  // HasAndroidInjectorのみでおk
  HasAndroidInjector {

  // 型変数がAnyになる
  @Inject lateinit var androidInjector: DispatchingAndroidInjector<Any>

  // 返り値の型変数がAnyになる
  override fun androidInjector(): AndroidInjector<Any> {
    DaggerAppComponent.factory().create(this).inject(this)
    return androidInjector
  }
}

今まではActivity用、Fragment用、Service用などのクラスごとにDispatchingAndroidInjectorがありましたが、それが1つのDispatchingAndroidInjector<Any>まとまりました。

Activity, Fragment

HasSupportFragmentInjectorなどのInjectorは、HasAndroidInjectorに置き換えます。

class MainActivity : AppCompatActivity(),
  // HasSupportFragmentInjectorの代わりに、HasAndroidInjectorを使う
  HasAndroidInjector {

  @Inject lateinit var androidInjector: DispatchingAndroidInjector<Any>

  override fun onCreate(savedInstanceState: Bundle?) {
    AndroidInjection.inject(this) // ここは一緒
    ...
  }

  override fun androidInjector(): AndroidInjector<Any> {
    return androidInjector
  }
}

---以下Fragment---

class MainFragment : Fragment() {
  override fun onAttach(context: Context) {
    AndroidSupportInjection.inject(this) // ここは一緒
    ...
  }
}

となります。従来の***Injectorが汎用的なHasAndroidInjectorまとまりました😃

大きなコードの修正は必要なさそうです。

なぜこの変更が入ったか?

ronshapiroさんが以下のツイートをしていました。

今後、androidxのサポートを柔軟に対応するために必要だった変更のようです。

DaggerApplicationや、DaggerAppCompatActivity、DaggerSupportFragmentなどを使っている場合

2.23では、これらの基底クラスでHasAndroidInjectorを使っているので特に対応は必要ありません。

// HasAndroidInjectorを使う実装に置き換わっている
@Beta
public abstract class DaggerApplication extends Application implements HasAndroidInjector {
  ...
}

唯一、AppComponentではAndroidSupportInjectionModuleを使っていると思うのでそこの置き換えは必要です。

まとめ

Written by