Dagger 在 superclass 和 sub-class 上注入

Dagger inject on superclass and sub-class

基础片段class

open class BaseFragment : Fragment() {

    @Inject lateinit var apiManager: ApiManager
    @Inject lateinit var eventBus: EventBus

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        App.getInstance().component.inject(this)
    }

    override fun onStop() {
        eventBus.unreg(this)
        super.onStop()
    }

    override fun onStart() {
        super.onStart()
        eventBus.reg(this)
    }
}

房间片段class

class RoomsFragment : BaseFragment() {

    @Inject lateinit var roomAdapter: RoomsAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        App.getInstance().component.inject(this)
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater?.inflate(R.layout.fragment_rooms_fragment_new, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        recyclerView.adapter = roomAdapter //This line throws null or lateinit property roomAdapter has not been initialized
    }
}

适配器模块class

@Module(includes = AppModule.class)
public class AdapterModule {

    @Provides //App module has EventBus so i included it in Module
    RoomsAdapter provideRoomsAdapter(EventBus eventBus) {
        return new RoomsAdapter(eventBus);
    }
}

应用组件class

@Singleton
    @Component(modules = {AppModule.class, AdapterModule.class})
    public interface ApplicationComponent {
        void inject(ApiManager apiManager);
        void inject(BaseFragment baseFragment);
    }

如您所见,我正在尝试在 superclass 和 sub class 中注入对象,但它并没有按预期工作。 BaseFragment 注入的对象可以找到,但 RoomsFragment 注入失败。任何解决方案?

修复: 我忘了在 ApplicationComponent 中为 sub-classRoomsFragment 添加接口。由于它的 superclass BaseFragment 接口存在,它在编译时没有抛出任何错误。

@Singleton
    @Component(modules = {AppModule.class, AdapterModule.class})
    public interface ApplicationComponent {
        void inject(RoomsFragment roomsFragment);
        void inject(ApiManager apiManager);
        void inject(BaseFragment baseFragment);
    }

试试这个:

@Singleton
        @Component(modules = {AppModule.class, AdapterModule.class})
        public interface ApplicationComponent {
            void inject(ApiManager apiManager);
            void inject(BaseFragment baseFragment);
            void inject(RoomsFragment roomsFragment);
        }

@Component文档中members injection methods的文档描述了相关行为。

您似乎在尝试注入 RoomsFragment 的成员。通过添加接受 RoomsFragment 的方法,您将注入 RoomsFragment@Inject 成员和任何超类型(在本例中为“BaseFragment”)。

另一方面,如果您调用接受 BaseFragment 的成员注入方法,您将注入 BaseFragment@Inject 个成员,但 不会 任何子类型的任何成员。因此,为抽象类型定义成员注入方法几乎不是一个好主意。

在最初的问题中,由于所有成员注入方法都被定义为彼此的重载,这使问题变得复杂。这意味着您将根据重载的解决方式为给定类型获得不同的注入行为。请参阅 有效 Java 2:项目 41 以了解有关为什么这些重载容易出错的更多背景信息。

还值得注意的是,在原始代码示例中有一个 ApiManager 的成员注入方法,但该类型作为实例注入 BaseFragment。注入成员传递地解决依赖关系,因此无需在组件上为 ApiManager 定义任何方法。

因此,为了注入 RoomsFragment 的所有成员(已声明和继承),只需为 RoomsFragment 定义一个成员注入方法:

@Singleton
@Component(modules = {AppModule.class, AdapterModule.class})
public interface ApplicationComponent {
  void inject(RoomsFragment roomsFragment);
}