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);
}
基础片段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);
}