简体   繁体   English

匕首2-无法将成员注入原始类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM