Android Dagger跨模块组件作用域与生命周期疑问
你的项目结构包含主模块(main module)和核心模块(core module),相关代码如下:
主模块MainComponent代码
// 依赖于CoreComponent @Component(modules = [MyModule::class], dependencies = [CoreComponent::class]) @FeatureScope interface MainComponent { fun inject(mainActivity: MainActivity) }
MainComponent依赖CoreComponent,使用自定义作用域@FeatureScope。
核心模块CoreComponent及相关代码
@Component(modules = [CoreModule::class]) @Singleton interface CoreComponent { fun getExpensiveObject(): ExpensiveObject } @Module class CoreModule { @Provides @Singleton fun provideExpObj(): ExpensiveObject = ExpensiveObject() }
CoreComponent使用Dagger内置的@Singleton作用域。
Application类中组件构建代码
class MyApplication : Application() { override fun onCreate() { super.onCreate() // 构建主组件及核心组件 mainComponent = DaggerMainComponent .builder() .myModule(MyModule()) .coreComponent(DaggerCoreComponent.builder().build()) .build() } }
问题1:从生命周期角度看,是否因@Singleton与@FeatureScope注解,MainComponent中对象的生命周期比CoreComponent中的更短?
答案是不一定,核心要看组件实例本身的生命周期,而非注解本身。
Dagger的作用域注解(比如@Singleton、@FeatureScope)的本质是:标记某个对象的生命周期与所属组件实例的生命周期完全绑定。具体来说:
- 标注
@Singleton的对象,生命周期和CoreComponent实例完全一致 - 标注
@FeatureScope的对象,生命周期和MainComponent实例完全一致
如果你的MainComponent实例是在Activity中创建、随Activity销毁而被释放,那它的对象生命周期自然比CoreComponent短;但像你现在的实现,两个组件都在Application中创建并被持有,它们的生命周期和应用进程完全同步,这时候两者的对象生命周期并没有长短之分。
注解只是定义了「对象与哪个组件绑定」,不会自动触发组件实例的提前销毁。
问题2:由于组件均在Application的onCreate()(应用运行入口)中构建,是否即使组件标注不同作用域注解,其对象生命周期仍与整个应用相同?
完全正确!
你现在的代码里,两个组件实例都被Application的成员变量持有,只要应用进程不销毁,这两个组件就会一直存在。不管你用@Singleton还是自定义的@FeatureScope,绑定到这些组件上的对象都会一直存活,直到应用进程结束。
这里容易混淆的点是:Dagger的@Singleton并不是「自动让对象活整个应用生命周期」,而是「对象的生命周期和它所属的@Singleton组件实例一致」——如果你的@Singleton组件是在Activity里创建的,那它的对象生命周期也只会和Activity一样长,只是在这个Activity范围内是单例而已。
如果想要让@FeatureScope的对象生命周期更短(比如和页面绑定),你需要在对应的页面(比如Activity/Fragment)中创建MainComponent,并且在页面销毁时主动释放对MainComponent的引用,这样组件实例被回收后,它绑定的对象也会被GC回收。
内容的提问来源于stack exchange,提问作者Leem

