【问题标题】:Dagger inject on superclass and sub-class匕首注入超类和子类
【发布时间】:2016-12-26 06:17:39
【问题描述】:

BaseFragment 类

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)
    }
}

RoomsFragment 类

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
    }
}

AdapterModule 类

@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);
    }
}

AppComonent 类

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

如您所见,我正在尝试在超类和子类中注入对象,但它没有按预期工作。 BaseFragment 注入的对象可以找到,但 RoomsFragment 注入失败。有什么解决办法吗?

修复: 我忘记在 ApplicationComponent 中添加子类RoomsFragment 的接口。由于它的超类BaseFragment 接口存在,它在编译时没有抛出任何错误。

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

【问题讨论】:

  • 您在组件中定义了 RoomsFragment?
  • 是的,我做到了.....
  • 希望你在RoomsFragment的真实代码App.getInstance().component.inject(this)中没有注释这个。?
  • 我尝试了两种方式。但没有运气。
  • 拆分组件试试。

标签: android kotlin dagger-2


【解决方案1】:

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

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

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

在最初的问题中,由于所有成员注入方法都被定义为彼此的重载,因此这很复杂。这意味着对于给定类型,您将获得不同的注入行为,具体取决于重载的解决方式。请参阅Effective Java 2:Item 41,了解有关这些重载容易出错的原因的更多背景信息。

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

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

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

【讨论】:

    【解决方案2】:

    试试这个:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      • 2017-06-03
      • 1970-01-01
      相关资源
      最近更新 更多