【问题标题】:Android retrofit how to show No data message when empty json arrayAndroid改造如何在空json数组时显示无数据消息
【发布时间】:2020-11-04 19:31:13
【问题描述】:

我正在使用改造从我的服务器检索数据 - 这是一个用户搜索:

        ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
    Call<List<Movie>> call = apiService.getSearch(lng, 0, newText);

    call.enqueue(new Callback<List<Movie>>() {

        @Override
        public void onResponse(@NonNull Call<List<Movie>> call, @NonNull Response<List<Movie>> response) {
            
            movieList = response.body();
            if (dialog != null) {
                dialog.dismiss();  dialog = null;
            }

            if (response.isSuccessful()) {
                recyclerAdapter.setMovieList(movieList);
            } else {

                showMsgSnack(getString(R.string.Nodata));
            }

        }

        @Override
        public void onFailure(@NonNull Call<List<Movie>> call, @NonNull Throwable t) {
            if (dialog != null) {
                dialog.dismiss();  dialog = null;
            }

            if(t instanceof UnknownHostException){

                showMsgSnack(getString(R.string.Network));
            }

            else if(t instanceof SocketTimeoutException){
                showMsgSnack(getString(R.string.ServerTimeout));
            }

            else {
                showMsgSnack(getString(R.string.ServerError));
            }
        }
    });

Json 是通过服务器中的 PHP 生成的。如果搜索成功,json会返回[{"title": "sometitle",...}].

但如果数据库中没有匹配项,我将返回一个空的 {}。

但在 android 中它会失败并显示 ServerError 消息。在这种情况下,我想显示一些消息为未找到匹配项。

我该如何处理这个响应?

我还为 Nullpointerexception 创建了一个默认回调,但这仍然不起作用:

        call.enqueue(new DefaultCallback<>(new Callback<List<Movie>>() {

        @Override
        public void onResponse(@NonNull Call<List<Movie>> call, @NonNull Response<List<Movie>> response) {

            movieList = response.body();
            if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }

            if (response.isSuccessful()) {
                recyclerAdapter.setMovieList(movieList);
            } else {

                showMsgSnack(getString(R.string.Nodata));
            }
        }

        @Override
        public void onFailure(@NonNull Call<List<Movie>> call, @NonNull Throwable t) {
            if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }

            if (t instanceof UnknownHostException) {

                showMsgSnack(getString(R.string.Network));
            }

            if (t instanceof NullPointerException) {

                showMsgSnack(getString(R.string.Nodata));
            } else if (t instanceof SocketTimeoutException) {
                showMsgSnack(getString(R.string.ServerTimeout));
            } else {
                showMsgSnack(getString(R.string.ServerError));
            }

        }
    }));
}

public static class DefaultCallback<T> implements Callback<T> {

    private static final String TAG = "YOUR_TAG";
    private final Callback<T> callback;

    public DefaultCallback(Callback<T> callback) {
        this.callback = callback;
    }

    @Override
    public void onResponse(@NonNull Call<T> call, Response<T> response) {
        if (response.body() == null) {
            callback.onFailure(call, new NullPointerException("Empty response"));
        } else {
            callback.onResponse(call, response);
        }
    }

    @Override
    public void onFailure(@NonNull Call<T> call, Throwable t) {
        Log.e(TAG, t.toString());
        callback.onFailure(call, t);
    }
}

上面写着:YOUR_TAG: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

【问题讨论】:

    标签: android retrofit


    【解决方案1】:

    在 android 中收到 API 的响应后,您需要类型为 Movie 对象 (List) 的列表,类似于 [{"title": "sometitle",...}] 这个。

    但是当您在搜索中找不到任何内容时,您将返回“{}”

    这里你遇到了一个问题,这是因为你排除了 List 表示 Array 而 API 返回“{}”表示 Object。

    简单的解决方案不要发送对象“{}”发送数组“[]”并检查

    @Override
        public void onResponse(@NonNull Call<List<Movie>> call, @NonNull Response<List<Movie>> response) {
    
            movieList = response.body();
            if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }
    
            if (movieList.size() > 0) {
                recyclerAdapter.setMovieList(movieList);
            } else {
                showMsgSnack(getString(R.string.Nodata));
            }
        }
    

    希望您能理解,这会有所帮助!

    【讨论】:

    • 其实我之前也试过用数组[],但问题是我从来没有检查过movieList.size()。现在有了你的建议,它正在起作用。谢谢!
    猜你喜欢
    • 2021-04-19
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    相关资源
    最近更新 更多