在 MVP 模式中在哪里进行 HTTP 请求?

Where to do HTTP requests in MVP pattern?

我想用 Retrofit 做 GET 请求,但我不知道我需要在哪一层 MVP 模式上做。据我所知,Model将所有数据发送给Presenter,然后Presenter将数据显示在View上。所以,我认为最好的地方是模型。但是 Presenter 如何知道 Model 已经获取了所有数据并准备好将其传递给 Presenter?为此,我认为我需要使用在模型完成加载数据时通知 Presenter 的接口。但是谷歌搜索什么是最好的方法,我看到开发人员使用像 Repositories 和 Managers 这样的东西。但是我无法弄清楚他们每个人的作用。那么,如何解决问题呢?在 MVP 模式中创建 HTTP 请求的最佳位置是什么?如果是 Model,将所有数据发送到 Presenter 的最佳方式是什么?

您需要的是从您的模型到演示者的回调结构。我通常使用和推荐的是使用 RxJava,retrofit2 已经有一个返回 Observable 对象的选项,这使一切变得更容易。

假设您有一个像这样的端点,这是一个改造响应,returns 一个可观察的:

@Headers({"Content-Type: application/json", "Accept: application/json"})
@GET("/api/v1/banners")
Observable<Response<GetBannersResponse>> getBanners(
@Header("Authorization") String auth_token);

GetBannersResponse class 只是一个封装我的 json 响应的 POJO:

public class GetBannersResponse {
    List<Banner> banners;

    public List<Banner> getBanners() {
        return banners;
    }

    public void setBanners(List<Banner> banners) {
        this.banners = banners;
    }
}

我的模型(交互器)class 我喜欢这样调用 DataHandler:

public class MyDataHandler implements MyDataHandlerContract.DataHandler {


    private RetrofitAPI theCloud;

    private PreferencesUtil prefs;

    @Inject
    public CatalogDataHandler(TaskrAPIConfig theCloud, PreferencesUtil prefs) {
        this.theCloud = theCloud;
        this.prefs = prefs;
    }

    @Override
    public Observable<Response<GetBannersResponse>> getBanners() {
        return theCloud.getApiService().getBanners(prefs.getTokenFormatted());
    } 
}

你可以看到我正在从 Retrofit 调用中返回可观察对象。然后在我的演示者中,我只订阅这个可观察的并采取相应的行动:

 @Override
    public void getBanners() {
        dataHandler
                .getBanners()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Response<GetBannersResponse>>() {
                    @Override
                    public void onCompleted() {
                       //act on complete
                    }

                    @Override
                    public void onError(Throwable e) {
                        //act on error
                    }

                    @Override
                    public void onNext(Response<GetBannersResponse> getBannersResponseResponse) {
                       //act on result received
                    }
                });
    }