处理 Volley 中的错误(使用期货)?

A T*_*A T 5 java error-handling android dalvik android-volley

实现我的LoginActivity.java,我设置了另一个class名为的文件+ AuthClient,它大量使用了 Volley。UserLoginTask需要Boolean从它返回 adoInBackground以便远程调用登录成功/失败。

那么下面我可以用 volley 做一个同步请求吗?,我设置:

void login(final HashMap<String, String> data,
           Response.Listener<JSONObject> listener,
           Response.ErrorListener errorListener) {
    JsonObjectRequest req = new JsonObjectRequest(
            api_prefix + "/auth", new JSONObject(data), listener, errorListener
    );
    queue.add(req); // RequestQueue
}

boolean loginResponseHandler(RequestFuture<VolleyError> err_future,
                             RequestFuture<JSONObject> future) {
    try {
        VolleyError err_response = err_future.get();
        JSONObject response = future.get();
        System.out.println("response.toString() = " + response.toString());
        return true;
    } catch (InterruptedException | ExecutionException e) {
        System.err.println("e = " + e.toString());
        return false;
    } catch (Exception e) { // Even tried this!
        System.err.println("Exception::e = " + e.toString());
        throw e;
    }
}

@Override
protected Boolean doInBackground(Void... params) {
    RequestFuture<JSONObject> future = RequestFuture.newFuture();
    RequestFuture<VolleyError> err_future = RequestFuture.newFuture();

    login(/*omitted for brevity*/, err_future, future);
    return loginResponseHandler(err_future, future);
} // Actual code has login/loginResponseHandler in separate class+file, and more^
Run Code Online (Sandbox Code Playgroud)

但是查看调试日志,我收到错误消息(来自其他地方,而不是我正在调试的地方):

08-24 23:17:13.228 7255-7288 E/Volley:[177] BasicNetwork.performRequest:http://192.168.5.3 :3003/v1/api/auth 的意外响应代码 400

我打算如何处理错误?- 还有一个参考脚手架可以工作吗?

djo*_*djo 5

首先

VolleyError err_response = err_future.get();

如果请求没有错误,你会得到一些强制转换异常。

实际上,您不需要 2 个 Futures,因为 RequestFuture 实现了 Response 和 Error Listeners。

所以说到点子上了。

未来.get()

返回结果。如果发生错误,则抛出执行异常,其中可能包含 VolleyError 异常,如果接收到网络数据,则可能包含一些网络数据。您需要做的就是将内部异常转换为 VolleyError 并在 catch 语句中获取数据。

try {
    JSONObject response = future.get();
    System.out.println("response.toString() = " + response.toString());
    return true;
} catch (InterruptedException | ExecutionException e) {
    if (VolleyError.class.isAssignableFrom(e.getCause().getClass())) {
        VolleyError ve = (VolleyError) e.getCause();
        System.err.println("ve = " + ve.toString());
        if (ve.networkResponse != null) {
            System.err.println("ve.networkResponse = " +
                               ve.networkResponse.toString());
            System.err.println("ve.networkResponse.statusCode = " +
                               ve.networkResponse.statusCode);
            System.err.println("ve.networkResponse.data = " +
                               new String(ve.networkResponse.data));
            return false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新

至于“最佳客户端设计”,这取决于您所做的应用程序设计选择。但是,您必须了解的错误的重要事项很少:

错误可以是 3 种主要类型:协议/网络错误,有网络响应或没有网络响应,以及其他纯 java 和与处理请求/响应相关的错误,其中最常见的是解析数据。

处理错误的主要方法有 2 种,它们不是来自您的代码。

  1. 使用自定义重试策略
  2. 通知用户错误

通常,您可以将第一个用于某些网络和 5xx 错误,然后使用一些消息处理程序让用户知道发生了什么事。

同样,您如何实现这一点实际上取决于您的应用程序架构。我个人使用了很多 rxJava 并应用了某种数据流设计,我将所有错误都集中在一个地方,然后根据请求、错误本身和应用程序状态决定如何处理它们。

对于我的应用程序,我将jus(高度扩展的 volley)与 rx-jus 模块和基于rxHub 的RxQueueHub 类一起使用,因此我可以在一个地方获得所有处理程序可用的所有响应和错误。