Dagger2:向演示者注入 Api 模块(MVP)

Dagger2: inject Api Module to presenter (MVP)

我想问一下MVP和dagger的工作方式。所以,在 android 开发中,我们知道 Activity 和 fragment 是一个视图,我们通过实现观察者来制作演示者(在我的例子中,我使用 rxjava + retrofit)。在这种情况下,我使用匕首来注入 Rest 服务(网络组件 -> 改造)。

我仍然对向我的演示者注入 Rest 服务感到困惑,因为我找到的所有示例都是向 activity 注入。

这是我的代码。

视图:

public class PageFragment extends Fragment implements ScheduleViewInterface{
private ScheduleCursorAdapter scheduleAdapter;
@Inject RestApi restApiInject;
private SchedulePresenter mPresenterJson;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    App.getApiComponent(getActivity()).inject(this);
    mPresenterJson.fetchSchedule();
}

@Override
public Observable<ScheduleList> getSchedule() {
    return restApiInject.getScheduleListByUrl("url here");
}

作为主持人:

public class SchedulePresenter implements Observer<ScheduleList> {
private ScheduleViewInterface mInterface;

public SchedulePresenter(ScheduleViewInterface viewInterface){
    mInterface = viewInterface;
}

@Override
public void onCompleted() {
    mInterface.jsonCompleted();
}

@Override
public void onError(Throwable e) {
    mInterface.jsonError(e.getMessage());
}

@Override
public void onNext(ScheduleList scheduleList) {
    mInterface.jsonScheduleList(scheduleList);
}

public void fetchSchedules(){
    unSubscribeAll();
    subscribe(mInterface.getSchedule(), SchedulePresenter.this);
}

这是我的 dagger2 代码

@CustomScope
@Component(modules = ApiModule.class, dependencies = NetworkComponent.class)
public interface ApiComponent {
MainActivity inject(MainActivity activity);
PageFragment inject(PageFragment fragment);
}

Architecture pattern

最佳做法是创建一个交互器 class 来处理此问题,然后将该交互器注入演示者中。在下面的项目中查看我的代码以了解。主持人代码是:

public class PopularMoviesPresenterImpl implements PopularMoviesPresenter {

@Inject
public PopularMoviesInteractor interactor;

private PopularMoviesView view;
private Subscription subscription = Subscriptions.empty();

@Inject
public PopularMoviesPresenterImpl() {
}

@Override
public void setView(PopularMoviesView view) {
    this.view = view;
}

@Override
public void destroy() {
    if (subscription != null && !subscription.isUnsubscribed())
        subscription.unsubscribe();

    interactor.onDestroy();

    view = null;
    interactor = null;
}

@Override
public void loadPopularMoviesData(boolean isConnected, int page, int limit) {

    if (null != view) {
        view.showProgress();
    }

    subscription = interactor.loadPopularMovies(page, limit).subscribe(movies ->
            {
                if (null != view) {
                    view.hideProgress();
                    view.setPopularMoviesValue(movies);

                    if (!isConnected)
                        view.showOfflineMessage();
                }
            },
            throwable -> {
                if (null != view) {
                    view.hideProgress();
                }

                if (isConnected) {
                    if (null != view) {
                        view.showRetryMessage();
                    }
                } else {
                    if (null != view) {
                        view.showOfflineMessage();
                    }
                }
            });

}}

互动者是:

public class PopularMoviesInteractorImpl implements PopularMoviesInteractor {
private TraktApi api;
private SchedulerProvider scheduler;

private ReplaySubject<Movie[]> moviesDataSubject;
private Subscription moviesSubscription;

@Inject
public PopularMoviesInteractorImpl(TraktApi api, SchedulerProvider scheduler) {
    this.api = api;
    this.scheduler = scheduler;
}

@Override
public Observable<Movie[]> loadPopularMovies(int page, int limit) {
    if (moviesSubscription == null || moviesSubscription.isUnsubscribed()) {
        moviesDataSubject = ReplaySubject.create();

        moviesSubscription = api.getPopularMovies(page, limit, Constants.API_EXTENDED_FULL_IMAGES)
                .subscribeOn(scheduler.backgroundThread())
                .observeOn(scheduler.mainThread())
                .subscribe(moviesDataSubject);
    }

    return moviesDataSubject.asObservable();
}

@Override
public void onDestroy() {
    if (moviesSubscription != null && !moviesSubscription.isUnsubscribed())
        moviesSubscription.unsubscribe();
}}

交互界面:

public interface PopularMoviesInteractor {

Observable<Movie[]> loadPopularMovies(int page, int limit);

void onDestroy();}

并在您的模块中写入:

 @Provides
public PopularMoviesInteractor provideInteractor(PopularMoviesInteractorImpl interactor) {
    return interactor;}

交互器是通过构造注入提供的。(不过你可以通过简单的注入来实现)

这里是 mvp 的一个干净的例子: http://github.com/mmirhoseini/fyber_mobile_offers

我看到这个问题已经有人回答了。但是如果你想要一个关于如何在 MVP 架构中使用依赖注入的清晰示例,我真的建议你检查这个 boilerplate 因为它完全基于使用 Dagger2 的 DI 并且它遵循 MVP 架构。

样板当前处理的依赖项如下:

  • 数据库依赖:封装了所有的数据库操作。
  • 共享偏好依赖:处理共享偏好。
  • 本地文件依赖:处理保存文件。
  • 分析依赖:涵盖向分析后端报告事件的所有操作(GA、Segment、FB、Flurry ..)
  • 日志依赖:封装所有与日志相关的操作到您的控制台
  • Api依赖:封装了所有API相关操作

依赖注入的强大功能非常方便,尤其是对于测试而言,因为您可以轻松地将测试环境中的依赖项切换为虚拟依赖项。