Dagger注入超类和子类

Sai*_*Sai 1 android kotlin dagger-2

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

AppComonent类

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

正如您所看到的,我正在尝试在超类和子类中注入对象,但它并没有按预期工作.BaseFragment注入的对象可以找到但是RoomsFragment注入失败.有解决方案吗

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

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

gk5*_*885 5

的文档成员注射方法的在@Component文档描述的相关行为.

看起来你正试图注入成员RoomsFragment.通过添加一个接受的方法RoomsFragment,您将注入@Inject成员RoomsFragment和任何超类型(在本例中为"BaseFragment").

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

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

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

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

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