Dagger 2集成Conductor Controller:Controller无法注入ActivityDep的求助
你的核心问题在于Controller的绑定模块被错误地放在了全局的AppComponent中,而Activity级别的依赖(ActivityDep)属于ActivityScope的组件,Singleton级别的AppComponent无法向下提供ActivityScope的依赖,反过来Activity的组件可以继承AppComponent的Singleton依赖。下面是具体的修复步骤:
1. 调整组件层级,将ControllerBindingModule移到Activity的Subcomponent中
首先,修改你的AppComponent,移除ControllerBindingModule——因为它不属于全局单例组件的范畴:
@Singleton @Component(modules = { ApplicationModule.class, ActivityBindingModule.class, AndroidSupportInjectionModule.class, ConductorInjectionModule.class }) interface AppComponent extends AndroidInjector<App> { @Component.Builder abstract class Builder extends AndroidInjector.Builder<App> {} }
然后,在ActivityBindingModule中,给对应的Activity添加ControllerBindingModule作为子模块。这样Controller的注入器就会关联到Activity的Subcomponent,自然能访问Activity级别的依赖:
@Module public abstract class ActivityBindingModule { // 给你的MainActivity(或目标Activity)配置Subcomponent,并关联ControllerBindingModule @ActivityScope @ContributesAndroidInjector(modules = {ActivityModule.class, ControllerBindingModule.class}) abstract MainActivity contributeMainActivityInjector(); }
2. 确保Scope注解正确匹配依赖层级
为了避免依赖泄漏和确保依赖可见性,给不同层级的依赖添加对应的Scope:
// 全局单例Scope @Scope @Retention(RetentionPolicy.RUNTIME) public @interface Singleton {} // Activity生命周期的Scope @Scope @Retention(RetentionPolicy.RUNTIME) public @interface ActivityScope {} // Controller生命周期的Scope @Scope @Retention(RetentionPolicy.RUNTIME) public @interface ControllerScope {}
然后给你的依赖类/提供者添加对应注解:
ApplicationDependency:使用@SingletonActivityDependency:使用@ActivityScopeControllerDependency:使用@ControllerScope
3. 确认Application的ControllerInjector配置
确保你的Application类正确实现HasControllerInjector,让Conductor能找到对应的注入器:
public class App extends DaggerApplication { @Inject DispatchingControllerInjector controllerInjector; @Override protected AndroidInjector<? extends DaggerApplication> applicationInjector() { return DaggerAppComponent.create(); } @Override public ControllerInjector controllerInjector() { return controllerInjector; } }
4. 验证Controller的注入
现在你可以在MyController中正常注入ActivityDependency了:
public class MyController extends Controller { @Inject ApplicationDependency applicationDependency; @Inject ActivityDependency activityDependency; // 现在可以正常注入 @Inject ControllerDependency controllerDependency; @NonNull @Override protected View onCreateView(@NonNull LayoutInflater layoutInflater, @NonNull ViewGroup viewGroup) { ConductorInjection.inject(this); return layoutInflater.inflate(R.layout.controller_main, viewGroup, false); } }
原理说明
通过将ControllerBindingModule关联到Activity的Subcomponent,Controller的注入器会成为Activity组件的子注入器,既可以继承Activity组件中的ActivityDep,也能从AppComponent继承ApplicationDep,同时自己的ControllerDep也能被正确提供,完美匹配你预期的依赖层级。
内容的提问来源于stack exchange,提问作者timr

