未安装AndroidInjectionModule仍正常?需声明场景及异常问询
根据Dagger官方文档中关于Activity对象注入的说明,要求在应用组件中安装AndroidInjectionModule,但未安装该模块时程序仍运行正常。这是否意味着无需声明它?在何种场景下会出现异常?
示例代码
注入实例:
data class Food(val name: String)
Module:
@Module class FoodModule{ @Provides fun provideFood(): Food { return Food("cholocate") } }
BindingModule:
@Module abstract class MainActivityModule { @ContributesAndroidInjector(modules = [FoodModule::class]) abstract fun FoodShop(): MainActivity }
AppComponent(未安装AndroidInjectionModule):
@Component(modules = [MainActivityModule::class]) interface AppComponent{ fun inject(app: App) }
App:
class App : Application(), HasActivityInjector { @Inject lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity> override fun onCreate() { super.onCreate() DaggerAppComponent.create().inject(this) } override fun activityInjector(): AndroidInjector<Activity> { return dispatchingActivityInjector } }
MainActivity:
class MainActivity : AppCompatActivity() { @Inject lateinit var food: Food override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.d("test", "Get ${food.name}") } }
最终在MainActivity中成功获取到了chocolate。
哈哈,这个问题其实挺常见的,很多刚上手Dagger Android的开发者都会有这个疑惑!我来给你拆解清楚:
为什么你的代码没装AndroidInjectionModule也能正常运行?
核心原因在于你用了@ContributesAndroidInjector注解。在Dagger 2.10及以后的版本中,当你使用这个注解时,Dagger会自动帮你生成一系列代码,其中就包含了MainActivity对应的注入器绑定,以及间接提供了DispatchingAndroidInjector<Activity>所需的依赖。
简单来说,@ContributesAndroidInjector已经替你完成了原本需要AndroidInjectionModule来提供的部分基础绑定工作,所以在这个只涉及单个Activity注入的简单场景里,你完全不需要手动安装AndroidInjectionModule。
哪些场景下不装AndroidInjectionModule会出现异常?
虽然你的场景没问题,但在以下几种情况中,不安装AndroidInjectionModule肯定会报错:
- 手动实现AndroidInjector.Factory注入组件时:如果你不用
@ContributesAndroidInjector,而是自己写AndroidInjector.Factory来创建Activity/Fragment的注入器,那么你必须依赖AndroidInjectionModule提供的Map<Class<? extends Activity>, AndroidInjector.Factory<? extends Activity>>绑定,否则Dagger找不到对应的映射关系。 - 注入系统级Android组件时:当你需要注入
BroadcastReceiver、Service、ContentProvider这些系统组件时,AndroidInjectionModule中包含了这些组件的基础注入绑定,没装的话Dagger无法完成这些组件的注入。 - 使用旧版本Dagger时:在Dagger 2.9及更早的版本中,
@ContributesAndroidInjector还不存在,必须显式安装AndroidInjectionModule才能实现Android组件的注入,否则直接编译报错。 - 依赖泛型Android组件的注入器时:如果你的代码中需要直接注入
DispatchingAndroidInjector<Fragment>或者其他基础Android组件类型的注入器,而没有通过@ContributesAndroidInjector覆盖对应的绑定,那么必须依靠AndroidInjectionModule来提供这些基础绑定。
总结
简单场景下(比如只用@ContributesAndroidInjector处理Activity注入),确实可以不用显式声明AndroidInjectionModule。但从规范和兼容性角度来说,我还是建议你在AppComponent中加上它——一来符合官方文档的建议,二来可以避免后续扩展功能时突然遇到绑定缺失的问题,毕竟多这一行代码几乎没有成本。
内容的提问来源于stack exchange,提问作者Mumi

