[英]Dagger 2 - Cannot inject members into raw type
I need to have three levels of inheritance and inject with dagger2 我需要具有三个继承级别,并使用dagger2注入
1.MainActivity 1.MainActivity
--1.1 MainSubActivity --1.1 MainSubActivity
----1.1.1 MainSubActivityOne ---- 1.1.1 MainSubActivityOne
----1.1.2 MainSubActivityTwo (The same structure as MainSubActivityOne) ---- 1.1.2 MainSubActivityTwo(与MainSubActivityOne的结构相同)
MainActivity 主要活动
public abstract class MainActivity<T extends MainPresenter> extends BaseActivity implements MainView{
@Inject
protected T mPresenter;
}
MainPresenter MainPresenter
public abstract class MainPresenter<T extends MainView> extends BasePresenter<T> { ... }
MainView 的MainView
public interface MainView extends BaseView{ ... }
-- MainSubActivity -MainSubActivity
public abstract class MainSubActivity extends MainActivity<MainSubPresenter> implements MainSubView { ... }
-- MainSubPresenter -MainSubPresenter
public abstract class MainSubPresenter<T extends MainSubView> extends MainPresenter<T> { ... }
-- MainSubView -MainSubView
public interface MainSubView extends MainView { ... }
---- MainSubActivityOne (Same as MainSubActivityTwo): ---- MainSubActivityOne(与MainSubActivityTwo相同):
public class MainSubActivityOne extends MainSubActivity implements MainSubViewOne{
@Override
protected void onCreatePresenter(){
mPresenter.setView(this);
mPresenter.onCreate();
}
@Override
protected void initializeDagger() {
getActivityComponent().inject(this);
}
}
---- MainSubPresenterOne (Same as MainPresenterTwo): ---- MainSubPresenterOne(与MainPresenterTwo相同):
public class MainSubPresenterOne extends MainSubPresenter<MainSubViewOne> { ... }
---- MainSubViewOne (Same as MainSubViewTwo): ---- MainSubViewOne(与MainSubViewTwo相同):
public interface MainSubViewOne extends MainSubView { ... }
ActivityComponent ActivityComponent
@PerActivity
@Component(dependencies = ApplicationComponent.class, modules =
{ActivityModule.class})
public interface ActivityComponent {
void inject(MainActivity mainActivity);
}
ActivityModule ActivityModule
@Provides
@PerActivity
MainPresenter provideMainPresenter() {
return new MainSubPresenterOne();
}
When I had only two levels, all is ok, but now I obtain this error: 当我只有两个级别时,一切正常,但是现在我收到此错误:
...components/ActivityComponent.java:90: error: [Dagger/MembersInjection] Cannot inject members into raw type com.example.main.MainActivity
void inject(MainActivity mainActivity);
^
com.example.main.MainActivity is injected at
...components.ActivityComponent.inject(com.example.main.MainActivity)
If I change the activityComponent to: 如果我将activityComponent更改为:
void inject(MainSubActivityOne activity);
void inject(MainSubActivityTwo activity);
I obtain the next error instead: 我得到了下一个错误:
.../components/ActivityComponent.java:92: error: [Dagger/MissingBinding] com.example.main.MainSubPresenterOne cannot be provided without an @Provides-annotated method.
void inject(MainSubActivityOne mainActivity);
^
com.example.main.MainSubPresenter is injected at
com.example.main.MainActivity.mPresenter
com.example.main.MainSubPresenterOne is injected at
...components.ActivityComponent.inject(com.example.main.MainSubActivityOne)
This line is your problem: 这行是你的问题:
void inject(MainActivity mainActivity);
MainActivity<T>
needs a generic type argument, but that's irrelevant. MainActivity<T>
需要泛型类型参数,但这无关紧要。 It's an abstract class. 这是一个抽象类。 You're not injecting this common parent class.
您没有注入这个普通的父类。 You're injecting the instances of its concrete children.
您正在注入其具体子级的实例。 Here's what you should do instead:
您应该改用以下方法:
void inject(MainSubActivityOne activity);
void inject(MainSubActivityTwo activity);
[Dagger/MissingBinding] com.example.main.MainSubPresenterOne cannot be provided without an @Provides-annotated method.
如果没有@Provides注释的方法,则无法提供[Dagger / MissingBinding] com.example.main.MainSubPresenterOne。
This is all true. 这都是真的。 Your
MainSubActivityOne
expects a MainSubPresenterOne
here: 您的
MainSubActivityOne
希望在这里有MainSubPresenterOne
:
@Inject
protected T mPresenter;
Yet you only created a binding for MainPresenter
: 但是,您只为
MainPresenter
创建了一个绑定:
@Provides
@PerActivity
MainPresenter provideMainPresenter() {
return new MainSubPresenterOne();
}
This means that Dagger knows only how to inject a MainPresenter
, it doesn't care that the MainPresenter
is actually a MainSubPresenterOne
. 这意味着Dagger只知道如何注入
MainPresenter
,并不在乎MainPresenter
实际上是MainSubPresenterOne
。
Instead, what I would do is to scope the concrete presenters and let them have an @Inject
constructor: 相反,我要做的是确定具体演示者的范围,并让他们具有
@Inject
构造函数:
@PerActivity
public class MainSubPresenterOne extends MainSubPresenter<MainSubViewOne> {
@Inject
public MainSubPresenterOne() {
// ...
}
// ...
}
Now Dagger knows how to inject MainSubPresenterOne
. 现在Dagger知道如何注入
MainSubPresenterOne
。 Remove the @Provides
method. 删除
@Provides
方法。
I recommend the official documentation , which – among other things – explains that @Provides
is a kind of last resort and you should prefer @Inject
on the types under your control. 我建议使用官方文档 ,该文档尤其说明了
@Provides
是一种不得已的方法,对于您所控制的类型,您应该首选@Inject
。
Alternatively you would 或者你会
@Inject
protected MainPresenter mPresenter;
and create a separate subcomponent for each of your activities with a module providing the actual presenter: 并使用提供实际演示者的模块为每个活动创建一个单独的子组件 :
@Module
abstract class MainSubActivityOneModule {
@Binds
abstract MainSubPresenter<MainSubViewOne> bindMainPresenter(MainSubPresenterOne impl);
}
This assumes that the activity doesn't care about the concrete implementation of its presenter, which may or may not be what you want. 假定活动不关心其演示者的具体实现,这可能是您想要的,也可能不是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.