凌空 deliverResponse 未被调用
Volley deliverResponse not being called
我正在使用 Volley,我看到了 parseNetworkResponse
被调用,一切正常。解析很好,我可以在日志中看到
而且我不 return null。
但出于某种原因,没有调用 deliverResponse?
为什么会发生这种情况或者我该如何调试它?
连这个:
@Override
protected Response<Object> parseNetworkResponse(NetworkResponse response) {
Log.i(“TEST”, "Returning nothing from dummy parseNetworkResponse....");
Response<Object> jsonResponse = Response.success(new Object(), HttpHeaderParser.parseCacheHeaders(response));
Log.i("TEST", "Returning nothing....");
return jsonResponse;
}
虽然我可以在 LOGCAT
中看到日志,但最终并没有调用 deliverResponse
更新:
我通过调试器并最终进入 NetworkDispatcher 中的代码(在网络解析完成和 post-响应之后)
request.markDelivered();
mDelivery.postResponse(请求,响应);
然后执行ExecutorDelivery.postResponse中的代码:
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
那最终会调用 mRequest.deliverResponse(mResponse.result);
但是当我在 ResponseDeliveryRunnable.run 中添加断点时,代码不会中断,因此我假设调用 deliverResponse 的 运行nable 不是 运行.
知道为什么会发生这种情况吗?
您还应该在 Network Response
中查找错误并通知 Volley 而不是使用 Object,您还需要重写 parseNetworkError, deliverResponse
方法。看我的例子(请不要被这么多样板代码淹没)
public interface JsonParser_<T> {
public T parseResponse_(JSONObject json);
public T parseResponse_(JSONArray json);
}
/**
*
* @param tag
* : to tag your request with some string, so that you can cancel
* them any time
* @param method
* <pre>
* int DEPRECATED_GET_OR_POST = -1;
* int GET = 0;
* int POST = 1;
* int PUT = 2;
* int DELETE = 3;
* int HEAD = 4;
* int OPTIONS = 5;
* int TRACE = 6;
* int PATCH = 7;
* </pre>
* @param url
* URL to hit
* @param postParams
* Parameters that embeds with the URL itself
* @param headerParams
* Parameters that goes inside header
* @param jsonDelivery
* Listener will be called with JSON so that you can parse your
* JSON off the UI thread
* @param resultDelivery
* It will return the resulf of delivery, very important to
* return the result in the first listener in parsing JSON
* @param errorListener
* It anything goes wrong
*/
@SuppressWarnings("hiding")
protected final <T> void fetchAndParseResponse(final String tag,
final int method, final String url,
final Map<String, String> postParams,
final Map<String, String> headerParams,
final JsonParser_<T> jsonDelivery,
final Response.Listener<T> resultDelivery,
final Response.ErrorListener errorListener) {
AppContext.requestQueue.start();
AppContext.requestQueue.add(new Request<T>(method, url,
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
setException(error);
if (errorListener != null)
// errorListener.onErrorResponse(wrapError(error));
errorListener.onErrorResponse(error);
}
}) {
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
T pojo = null;
statusCode = response.statusCode;
try {
String jsonString = new String(response.data, "UTF-8");
char char_ = new JSONTokener(jsonString).next();
if (char_ == '{') {
JSONObject json = new JSONObject(jsonString);
// isResponseOk(json);
pojo = jsonDelivery.parseResponse_(json);
} else {
JSONArray json = new JSONArray(jsonString);
pojo = jsonDelivery.parseResponse_(json);
}
} catch (UnsupportedEncodingException e) {
setException(e);
// return Response.error(wrapError(new VolleyError(e)));
return Response.error((new VolleyError(e)));
} catch (JSONException e) {
setException(e);
// return Response.error(wrapError(new VolleyError(e)));
return Response.error((new VolleyError(e)));
}
return Response.success(pojo,
HttpHeaderParser.parseCacheHeaders(response, true));
}
@Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
if (volleyError.networkResponse != null
&& volleyError.networkResponse.data != null) {
VolleyError error = new VolleyError(new String(
volleyError.networkResponse.data));
volleyError = error;
}
return volleyError;
}
@Override
protected void deliverResponse(T response) {
if (resultDelivery != null)
resultDelivery.onResponse(response);
else
VolleyLog.wtf("No listener attached with %s class", this
.getClass().getName());
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
if (headerParams == null) {
Map<String, String> map = new HashMap<String, String>(1);
if (AppContext.userPojo != null) {
map.put("sid", AppContext.userPojo.SID);
}
return map;
} else {
if (AppContext.userPojo != null) {
headerParams.put("sid", AppContext.userPojo.SID);
}
}
return headerParams;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
if (postParams == null)
return super.getParams();
else
return postParams;
}
}.setRetryPolicy(new DefaultRetryPolicy()).setTag(tag));
}
用法:
fetchAndParseResponse(tag, Method.POST, AZ_API.SOME_URL, null, null, new JsonParser_<StatusMessage>() {
@Override
public StatusMessage parseResponse_(JSONObject json) {
requestStatus = parseStatus(json);
message = parseMessage(json);
StatusMessage msg = new StatusMessage();
msg.setMessage(message);
msg.setStatus(requestStatus);
return msg;
}
@Override
public StatusMessage parseResponse_(JSONArray json) {
return null;
}
}, listener, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
errorListener.onErrorResponse(error);
}
});
检查您的 volley 日志以获取线索,正如上面的一些回答者所提到的。我使用别名来过滤 volley 日志,如下所示:
alias vlog='adb shell setprop log.tag.Volley VERBOSE && adb logcat -Cv threadtime | grep -Ii '\''volley'\'''
当我遇到这个问题时,我注意到有问题的特定请求会在日志中显示以下内容:
04-02 17:22:41.309 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
04-02 17:22:41.309 21639 21639 D Volley : [1] MarkerLog.finish: (+10 ) [233] cache-queue-take
04-02 17:22:41.310 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [233] cache-miss
04-02 17:22:41.313 21639 21639 D Volley : [1] MarkerLog.finish: (+1 ) [234] network-queue-take
04-02 17:22:41.314 21639 21639 D Volley : [1] MarkerLog.finish: (+227 ) [234] network-http-complete
04-02 17:22:41.314 21639 21639 D Volley : [1] MarkerLog.finish: (+3 ) [234] network-parse-complete
04-02 17:22:41.315 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [234] post-response
04-02 17:22:41.315 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [ 1] canceled-at-delivery
向右滚动,您会注意到最后一行中的 [ 1] canceled-at-delivery
。如果在交付时发现原始请求已通过 cancel()
取消,则由 Volley 打印此文件。我有一个不幸的代码路径,它作为 "cleanup action" 过早地导致请求在交付之前被取消,导致 Volley 丢弃它。
来自 com.android.volley.ExecutorDelivery:93:
// If this request has canceled, finish it and don't deliver.
if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}
希望对您有所帮助。
我正在使用 Volley,我看到了 parseNetworkResponse 被调用,一切正常。解析很好,我可以在日志中看到 而且我不 return null。 但出于某种原因,没有调用 deliverResponse? 为什么会发生这种情况或者我该如何调试它?
连这个:
@Override
protected Response<Object> parseNetworkResponse(NetworkResponse response) {
Log.i(“TEST”, "Returning nothing from dummy parseNetworkResponse....");
Response<Object> jsonResponse = Response.success(new Object(), HttpHeaderParser.parseCacheHeaders(response));
Log.i("TEST", "Returning nothing....");
return jsonResponse;
}
虽然我可以在 LOGCAT
中看到日志,但最终并没有调用 deliverResponse更新:
我通过调试器并最终进入 NetworkDispatcher 中的代码(在网络解析完成和 post-响应之后)
request.markDelivered();
mDelivery.postResponse(请求,响应);
然后执行ExecutorDelivery.postResponse中的代码:
mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
那最终会调用 mRequest.deliverResponse(mResponse.result);
但是当我在 ResponseDeliveryRunnable.run 中添加断点时,代码不会中断,因此我假设调用 deliverResponse 的 运行nable 不是 运行.
知道为什么会发生这种情况吗?
您还应该在 Network Response
中查找错误并通知 Volley 而不是使用 Object,您还需要重写 parseNetworkError, deliverResponse
方法。看我的例子(请不要被这么多样板代码淹没)
public interface JsonParser_<T> {
public T parseResponse_(JSONObject json);
public T parseResponse_(JSONArray json);
}
/**
*
* @param tag
* : to tag your request with some string, so that you can cancel
* them any time
* @param method
* <pre>
* int DEPRECATED_GET_OR_POST = -1;
* int GET = 0;
* int POST = 1;
* int PUT = 2;
* int DELETE = 3;
* int HEAD = 4;
* int OPTIONS = 5;
* int TRACE = 6;
* int PATCH = 7;
* </pre>
* @param url
* URL to hit
* @param postParams
* Parameters that embeds with the URL itself
* @param headerParams
* Parameters that goes inside header
* @param jsonDelivery
* Listener will be called with JSON so that you can parse your
* JSON off the UI thread
* @param resultDelivery
* It will return the resulf of delivery, very important to
* return the result in the first listener in parsing JSON
* @param errorListener
* It anything goes wrong
*/
@SuppressWarnings("hiding")
protected final <T> void fetchAndParseResponse(final String tag,
final int method, final String url,
final Map<String, String> postParams,
final Map<String, String> headerParams,
final JsonParser_<T> jsonDelivery,
final Response.Listener<T> resultDelivery,
final Response.ErrorListener errorListener) {
AppContext.requestQueue.start();
AppContext.requestQueue.add(new Request<T>(method, url,
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
setException(error);
if (errorListener != null)
// errorListener.onErrorResponse(wrapError(error));
errorListener.onErrorResponse(error);
}
}) {
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
T pojo = null;
statusCode = response.statusCode;
try {
String jsonString = new String(response.data, "UTF-8");
char char_ = new JSONTokener(jsonString).next();
if (char_ == '{') {
JSONObject json = new JSONObject(jsonString);
// isResponseOk(json);
pojo = jsonDelivery.parseResponse_(json);
} else {
JSONArray json = new JSONArray(jsonString);
pojo = jsonDelivery.parseResponse_(json);
}
} catch (UnsupportedEncodingException e) {
setException(e);
// return Response.error(wrapError(new VolleyError(e)));
return Response.error((new VolleyError(e)));
} catch (JSONException e) {
setException(e);
// return Response.error(wrapError(new VolleyError(e)));
return Response.error((new VolleyError(e)));
}
return Response.success(pojo,
HttpHeaderParser.parseCacheHeaders(response, true));
}
@Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
if (volleyError.networkResponse != null
&& volleyError.networkResponse.data != null) {
VolleyError error = new VolleyError(new String(
volleyError.networkResponse.data));
volleyError = error;
}
return volleyError;
}
@Override
protected void deliverResponse(T response) {
if (resultDelivery != null)
resultDelivery.onResponse(response);
else
VolleyLog.wtf("No listener attached with %s class", this
.getClass().getName());
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
if (headerParams == null) {
Map<String, String> map = new HashMap<String, String>(1);
if (AppContext.userPojo != null) {
map.put("sid", AppContext.userPojo.SID);
}
return map;
} else {
if (AppContext.userPojo != null) {
headerParams.put("sid", AppContext.userPojo.SID);
}
}
return headerParams;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
if (postParams == null)
return super.getParams();
else
return postParams;
}
}.setRetryPolicy(new DefaultRetryPolicy()).setTag(tag));
}
用法:
fetchAndParseResponse(tag, Method.POST, AZ_API.SOME_URL, null, null, new JsonParser_<StatusMessage>() {
@Override
public StatusMessage parseResponse_(JSONObject json) {
requestStatus = parseStatus(json);
message = parseMessage(json);
StatusMessage msg = new StatusMessage();
msg.setMessage(message);
msg.setStatus(requestStatus);
return msg;
}
@Override
public StatusMessage parseResponse_(JSONArray json) {
return null;
}
}, listener, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
errorListener.onErrorResponse(error);
}
});
检查您的 volley 日志以获取线索,正如上面的一些回答者所提到的。我使用别名来过滤 volley 日志,如下所示:
alias vlog='adb shell setprop log.tag.Volley VERBOSE && adb logcat -Cv threadtime | grep -Ii '\''volley'\'''
当我遇到这个问题时,我注意到有问题的特定请求会在日志中显示以下内容:
04-02 17:22:41.309 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [ 1] add-to-queue
04-02 17:22:41.309 21639 21639 D Volley : [1] MarkerLog.finish: (+10 ) [233] cache-queue-take
04-02 17:22:41.310 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [233] cache-miss
04-02 17:22:41.313 21639 21639 D Volley : [1] MarkerLog.finish: (+1 ) [234] network-queue-take
04-02 17:22:41.314 21639 21639 D Volley : [1] MarkerLog.finish: (+227 ) [234] network-http-complete
04-02 17:22:41.314 21639 21639 D Volley : [1] MarkerLog.finish: (+3 ) [234] network-parse-complete
04-02 17:22:41.315 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [234] post-response
04-02 17:22:41.315 21639 21639 D Volley : [1] MarkerLog.finish: (+0 ) [ 1] canceled-at-delivery
向右滚动,您会注意到最后一行中的 [ 1] canceled-at-delivery
。如果在交付时发现原始请求已通过 cancel()
取消,则由 Volley 打印此文件。我有一个不幸的代码路径,它作为 "cleanup action" 过早地导致请求在交付之前被取消,导致 Volley 丢弃它。
来自 com.android.volley.ExecutorDelivery:93:
// If this request has canceled, finish it and don't deliver.
if (mRequest.isCanceled()) {
mRequest.finish("canceled-at-delivery");
return;
}
希望对您有所帮助。