【问题标题】:Handling errors in Volley (with futures)?处理 Volley 中的错误(使用期货)?
【发布时间】:2016-12-31 16:25:10
【问题描述】:

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

所以跟随Can I do a synchronous request with 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^

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

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

我应该如何处理错误? - 还有参考脚手架可以使用吗?

【问题讨论】:

  • 主要问题是为什么?如果您使用的是RequestFuture&lt;T&gt;.get,为什么要使用 Volley?这没有任何意义......
  • Volley 仅用于来自主线程的异步查询。使用普通的 URLdoInBackground 中的内容
  • Selvin:因为在测试和其他使用AuthClient 的代码区域中,我不需要立即得到结果。我在这里 [对吗?] 所以现在我需要 doInBackground 来运行一个函数并返回结果。但也许还有另一种方式! - 不管我的实现是行不通的。
  • @Serg:Volley 做了很多缓存,这也很有用。

标签: java android error-handling android-volley dalvik


【解决方案1】:

首先

VolleyError err_response = err_future.get();

如果请求没有错误是不好的,你会得到一些转换异常。

实际上,您不需要 2 个 Future,因为 RequestFuture 实现了响应和错误侦听器。

言归正传。

future.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;
        }
    }
}

更新

关于“最佳客户端设计”,这取决于您所做的应用设计选择。但是,您必须知道一些重要的错误信息:

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

有两种主要方法可以处理并非来自您的代码的错误。

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

通常你可以使用第一个来处理一些网络和 5xx 错误,然后有一些消息处理程序让用户知道发生了帽子。

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

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

【讨论】:

  • 编辑了您的答案,因此它现在实际上 0) 编译,并且 1) 向我显示了我想要的数据。感谢您让我朝着正确的方向前进! - PS:关于客户端布局的任何提示,即:脚手架?
  • 信息量很大,但是从哪个文档中,或者您是如何发现 Execution 异常包含 VolleyError 异常的?
【解决方案2】:

啊,这很愚蠢,这是解决方案:

if (err_future != null) throw err_future.get();

loginResponseHandler 中的try 之后添加,替换:

VolleyError err_response = err_future.get();

现在错误被抛出并捕获,因此可以通过编程方式处理。

编辑:如何获得实际的网络响应? - 像状态码和错误正文?点赞:com.android.volley.NetworkResponse

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    相关资源
    最近更新 更多