尝试使用Dagger 2实现MVP - 如何在提供的演示者中获取对Activity的引用

Ste*_*hen 1 mvp android dependency-injection dagger-2

我正在尝试用MVP和Dagger建立一个应用程序,

视图是一个Activity其中实现了一个图界面.

public class OverviewActivity extends AppCompatActivity implements OverviewContract.View {

    @Inject OverviewPresenter presenter;

    @BindView(R.id.history_days) ListView HistoryLabels;
    @BindView(R.id.history_events) ListView HistoryEvents;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_overview);
        ButterKnife.bind(this);

        DaggerOverviewComponent.create().inject(this);

    }

    @Override
    public void showHistory(List<Exercise> history) {
      // ...
    }

    @Override
    public void updateScoreSlider(float value) {
      // ...
    }

    @OnClick(R.id.add_event_button)
    public void addEvent(View v){
      // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

演示看起来像这样

public class OverviewPresenter implements OverviewContract.Events {

    OverviewContract.View view;

    public OverviewPresenter( OverviewContract.View overviewView ) {
        view = overviewView;

    }

    @Override
    public void loadHistory() {
        // TODO
    }

    @Override
    public void addNewEvent() {
        // TODO
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到麻烦的地方是演示的提供者.其中一个依赖OverviewPresenterOverviewActivity,但我应该如何将实例OverviewActivity注入OverviewPresenter

@Module
public class PresenterModule {

    @Provides
    static OverviewPresenter provideOverviewPresenter(){
        return new OverviewPresenter(/* pass in the instance of the activity here?? */);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的组件看起来像

@Component(modules = {PresenterModule.class})
public interface OverviewComponent {

    void inject(OverviewActivity overviewActivity);
}
Run Code Online (Sandbox Code Playgroud)

请原谅我,如果这是基础,我仍然试图绕着匕首.

TLDR:
我如何设置它以便我的OverviewActivity可以注入一个OverviewPresenter,它本身注入了OverviewActivity的实例?

Dav*_*jak 9

  • 要提供匕首无法创建的东西,您需要使用模块.
  • 要提供您的演示者,您可以使用它来注释构造函数,@Inject而不需要使用模块 - 不应该.

由于您的视图实现了视图,因此您无法自己创建视图,也无法匕首.因此,创建一个模块来提供视图

@Module
public class OverviewModule {

    OverviewView mView;

    OverviewModule(OverviewView view) {
        mView = view;
    }

    @Provides
    static OverviewView provideOverviewView() {
        return mView;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后调整您的演示者以使用构造函数注入

public class OverviewPresenter implements OverviewContract.Events {

    OverviewContract.View view;

    @Inject
    public OverviewPresenter( OverviewContract.View overviewView ) {
        view = overviewView;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后只需将模块添加到组件中即可完成.

@Component(modules = {OverviewModule.class})
public interface OverviewComponent {

    void inject(OverviewActivity overviewActivity);
}
Run Code Online (Sandbox Code Playgroud)

现在只需注入你的演示者,你就完成了(像这样,可能会有拼写错误):

DaggerOverviewComponent.builder().overviewModule(new OverviewModule(this)).build()
        .inject(this);
Run Code Online (Sandbox Code Playgroud)