如何设计一个class,当数据下载完成后,可以从服务器传递数据

How to design a class that can pass data from server when data is finish downloading

我是 Android 开发新手,最近正在学习如何正确使用 MVP 模式。

现在我遇到了一个棘手的问题,希望能从这里得到一些有用的建议或解决方案。

首先是我的主持人

public class MVPPresenter {

    private MVPView mvpView;

    public MVPPresenter(MVPView mvpView) {
        this.mvpView = mvpView;
    }

    public void loadData() {
        mvpView.startLoading();
        final List<MVPModel> list = new ArrayList<>();
        //the part that I trying to extract starts here.
        Call call = DataRetriever.getDataByGet(URLCombiner.GET_FRONT_PAGE_ITEMS);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                mvpView.errorLoading();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    try {
                        JSONObject result = new JSONObject(response.body().string());
                        int errorCode = result.getInt("ErrorCode");
                        if (errorCode == 0) {
                            JSONArray value = result.getJSONObject("Value").getJSONArray("hot");
                            for (int i = 0; i < value.length(); i++) {
                                MVPModel mvpModel = new MVPModel();
                                String name = null;
                                String image = null;
                                try {
                                    name = value.getJSONObject(i).getString("title");
                                    image = URLCombiner.IP + value.getJSONObject(i).getString("pic");
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                                mvpModel.setName(name);
                                mvpModel.setImage(image);
                                list.add(mvpModel);
                            }
                            if (list.size() > 0) {
                                mvpView.successLoading(list);
                                mvpView.finishLoading();
                            } else {
                                mvpView.errorLoading();
                            }
                        } else {
                            mvpView.errorLoading();
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else {
                    mvpView.errorLoading();
                }
            }
        });
        //the part that I trying to extract ends here.
    }
}

如您所见,我正在尝试将使用 OKHttp 库的部分提取到 class(我称之为数据管理器)中,我希望它可以处理服务器和客户端之间的每项任务。但事情是这样的,当我试图将数据管理器的结果传递给演示者时,由于异步机制,我得到了 NullPointException。

我想知道如何在数据下载完成后将异步来自服务器的数据传递给演示者。

这是我理想的数据管理器,我知道这可能看起来很愚蠢,但我认为这可以使我的问题更清楚。

public class LoadServerData {

    private static JSONArray arrayData = new JSONArray();

    public static JSONArray getServerData() {
        Call call = DataRetriever.getDataByGet(URLCombiner.GET_FRONT_PAGE_ITEMS);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    try {
                        JSONObject result = new JSONObject(response.body().string());
                        int errorCode = result.getInt("ErrorCode");
                        if (errorCode == 0) {
                            arrayData = result.getJSONObject("Value").getJSONArray("hot");  //the data I would like to return.
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        return arrayData;   //this is gonna be an empty data.
    }
}

我已经阅读了一些可能可以解决我的问题的文章,但仍然没有得到很好的答案。也许我认为我使用了错误的关键字。希望你们能给我一些想法或解决方案来帮助我或启发我。

P.S。 OKhttp 库的版本是 3.7.0

创建一个简单的 Listener 以便在服务器调用完成时调用它:

public class LoadServerData {

    public static interface Listener {
        public void onSuccess(JSONArray data);
        public void onError(Exception error);
    }

    public static void getServerData(Listener listener) {
        Call call = DataRetriever.getDataByGet(URLCombiner.GET_FRONT_PAGE_ITEMS);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                listener.onError(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    try {
                        JSONObject result = new JSONObject(response.body().string());
                        int errorCode = result.getInt("ErrorCode");
                        if (errorCode == 0) {
                            JSONArray arrayData = result.getJSONObject("Value").getJSONArray("hot");  //the data I would like to return.
                            listener.onSuccess(arrayData);
                        } else {
                            listener.onError(...);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        listener.onError(e);
                    }
                } else {
                    listener.onError(...);
                }
            }
        });
    }
}