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

Dagger 2 - Cannot inject members into raw type

我需要三级继承,用dagger2注入

1.MainActivity

--1.1 MainSubActivity

----1.1.1 MainSubActivityOne

----1.1.2 MainSubActivityTwo(与MainSubActivityOne结构相同)

主要活动

public abstract class MainActivity<T extends MainPresenter> extends BaseActivity implements MainView{

     @Inject
     protected T mPresenter;

}

主讲人

public abstract class MainPresenter<T extends MainView> extends BasePresenter<T> { ... }

主视图

public interface MainView extends BaseView{ ... }

-- MainSubActivity

public abstract class MainSubActivity extends MainActivity<MainSubPresenter> implements MainSubView { ... }

-- MainSubPresenter

public abstract class MainSubPresenter<T extends MainSubView> extends MainPresenter<T> { ... }

-- MainSubView

public interface MainSubView extends MainView { ... }

---- 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(与 MainPresenterTwo 相同):

public class MainSubPresenterOne extends MainSubPresenter<MainSubViewOne> { ... }

---- MainSubViewOne(与 MainSubViewTwo 相同):

public interface MainSubViewOne extends MainSubView { ... }

ActivityComponent

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = 
{ActivityModule.class})
public interface ActivityComponent { 

    void inject(MainActivity mainActivity);

}

活动模块

@Provides
@PerActivity
MainPresenter provideMainPresenter() {
    return new MainSubPresenterOne();
}

当我只有两层时,一切正常,但现在我得到这个错误:

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

如果我将 activityComponent 更改为:

void inject(MainSubActivityOne activity);
void inject(MainSubActivityTwo activity);

我得到的是下一个错误:

.../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)

这一行是你的问题:

void inject(MainActivity mainActivity);

MainActivity<T> 需要泛型类型参数,但这无关紧要。这是一个摘要class。您没有注入这个共同的父 class。您正在注入其具体子项的实例。以下是您应该做的:

void inject(MainSubActivityOne activity);
void inject(MainSubActivityTwo activity);

[Dagger/MissingBinding] com.example.main.MainSubPresenterOne cannot be provided without an @Provides-annotated method.

这都是真的。您的 MainSubActivityOne 需要 MainSubPresenterOne 此处:

 @Inject
 protected T mPresenter;

但您只为 MainPresenter 创建了绑定:

@Provides
@PerActivity
MainPresenter provideMainPresenter() {
    return new MainSubPresenterOne();
}

这意味着 Dagger 只知道如何注入 a MainPresenter,它并不关心 MainPresenter 实际上是一个 MainSubPresenterOne.

相反,我要做的是确定具体演示者的范围,让他们有一个 @Inject 构造函数:

@PerActivity
public class MainSubPresenterOne extends MainSubPresenter<MainSubViewOne> { 

    @Inject
    public MainSubPresenterOne() {
        // ...
    }

    // ...
}

现在 Dagger 知道如何注入 MainSubPresenterOne。删除 @Provides 方法。

我推荐 official documentation,它解释了 @Provides 是一种最后的手段,你应该更喜欢 @Inject 在你控制的类型上。


或者你会

 @Inject
 protected MainPresenter mPresenter;

并为您的每个活动创建一个单独的 subcomponent,并提供一个提供实际演示者的模块:

@Module
abstract class MainSubActivityOneModule {

    @Binds
    abstract MainSubPresenter<MainSubViewOne> bindMainPresenter(MainSubPresenterOne impl);
}

这假定 activity 不关心其演示者的具体实现,这可能是也可能不是您想要的。