Android 改造 json 数组为空时如何显示无数据消息

Android retrofit how to show No data message when empty json array

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

        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会return喜欢[{"title": "sometitle",...}].

但是如果数据库中没有匹配项,我 return 只是一个空的 {}。

但在 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:预期 BEGIN_ARRAY 但在第 1 行第 2 列路径 $

BEGIN_OBJECT

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

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

这里你遇到了一个问题,这是因为你排除了 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));
        }
    }

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