Dagger:获取二级子组件创建的实例 解决Thing重复绑定问题
核心问题原因
编译错误本质是同一个Thing类型在Dagger的依赖树中存在两处绑定:一处是SubModule中的@Provides方法提供,另一处是SubCompThing关联的ModuleThing提供,Dagger不允许同一无修饰类型存在多个绑定源。
解决方案
核心原则是:Thing的绑定唯一由子组件SubCompThing负责提供,父组件层级完全不声明Thing的直接绑定,仅通过SubCompThing的工厂间接生产Thing实例,即可避免绑定冲突,同时保证每次调用都返回全新实例、每个Thing对应专属子组件。
步骤1:保留子组件SubCompThing的绑定逻辑
确保Thing的唯一绑定在子组件层级:
@Module interface ModuleThing { @Provides @ThingScope static Thing providesThing() { return new Thing(); } } @Subcomponent(modules = {ModuleThing.class}) @ThingScope public interface SubCompThing { // 暴露子组件内的Thing实例 Thing getThing(); // 声明子组件工厂,供父组件调用创建实例 @Subcomponent.Factory interface Factory { SubCompThing create(); // 如果创建子组件需要传入父组件的参数,直接加在这个方法的入参即可 } }
步骤2:删除父模块SubModule中的Thing绑定
移除SubModule里的@Provides Thing方法,仅声明SubCompThing为子组件即可,不要在父层级新增任何Thing类型的绑定:
@Module(subcomponents = {SubCompThing.class}) interface SubModule { // 不需要写任何Thing相关的Provider方法 }
步骤3:调整父组件SubComp的暴露逻辑
两种方式按需选择:
方式1(Java 8+推荐):通过接口默认方法封装Thing生产逻辑
直接在父组件内封装实例创建逻辑,上层调用方无感知:
@Subcomponent(modules = {SubModule.class}) @SubScope public interface SubComp { // 先暴露子组件工厂,Dagger会自动实现注入 SubCompThing.Factory subCompThingFactory(); // 封装getThing方法,上层直接调用即可拿到新实例 default Thing getThing() { SubCompThing thingComp = subCompThingFactory().create(); // 在这里添加你需要对thingComp做的自定义处理逻辑 return thingComp.getThing(); } }
每次调用getThing()都会创建全新的SubCompThing实例,对应生成全新的Thing,完全符合需求。
方式2(兼容低版本Java):单独封装Thing工厂类
如果不支持接口默认方法,可以单独封装一个工厂类,绑定到父组件即可:
// 自定义Thing生产工厂 public class ThingFactory { private final SubCompThing.Factory thingCompFactory; @Inject public ThingFactory(SubCompThing.Factory thingCompFactory) { this.thingCompFactory = thingCompFactory; } public Thing createNewThing() { SubCompThing thingComp = thingCompFactory.create(); // 自定义处理逻辑 return thingComp.getThing(); } } // 父组件直接暴露ThingFactory即可 @Subcomponent(modules = {SubModule.class}) @SubScope public interface SubComp { ThingFactory getThingFactory(); }
上层调用时每次调用createNewThing()就能拿到新实例,同样不会触发绑定冲突。
内容的提问来源于stack exchange,提问作者dave mankoff
相关产品推荐
相关产品推荐

