【问题标题】:Dagger 2 - Cannot inject members into raw typeDagger 2 - 无法将成员注入原始类型
【发布时间】:2019-09-12 20:47:29
【问题描述】:

我需要三级继承并用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{ ... }

-- 主子活动

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

-- MainSubPresenter

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

-- 主子视图

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 { ... }

活动组件

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

如果我将活动组件更改为:

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)

【问题讨论】:

    标签: android inheritance abstract-class dagger-2


    【解决方案1】:

    这一行是你的问题:

    void inject(MainActivity mainActivity);
    

    MainActivity&lt;T&gt; 需要一个泛型类型参数,但这无关紧要。这是一个抽象类。您没有注入这个公共父类。您正在注入其具体子代的实例。你应该这样做:

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

    [Dagger/MissingBinding] com.example.main.MainSubPresenterOne 不能在没有 @Provides 注释的方法的情况下提供。

    这都是真的。您的MainSubActivityOne 在这里需要MainSubPresenterOne

     @Inject
     protected T mPresenter;
    

    然而你只为MainPresenter创建了一个绑定:

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

    这意味着 Dagger 只知道如何注入 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);
    }
    

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

    【讨论】:

    • 我在 ActivityModule 中删除了 provideMainSubPresenterOne(..) 方法,在 MainSubPresenterOne 中我添加了 PerActivity 和 Inject 注释,但是我得到了这个错误: ...MainSubPresenter cannot be provided without an @Provides-带注释的方法。
    • @PabloGarcia 该消息说您正在尝试在某处注入MainSubPresenter。我不知道在哪里,它不在您已经发布的代码中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多