我在HTTP请求中遇到了一些奇怪的行为。我有一些用户说这个调用永远不会回来(微调器标记它的异步调用永远不会消失)。我之前已经看到过这种情况,但我把它归功于通过Charles Proxy的模拟器。到目前为止,我还没有在实际的手机上看过它。
我不确定会导致这种情况发生的原因,这就是我在这里发布的原因。这是调用,使用Jackson将结果反序列化为值对象。我看到模拟器冻结的两个点是httpclient.execute(httpGet);和getObjectMapper()。readValue(jp,SyncVO.class);。
在调试时,单步执行有问题的语句会导致调试器永远无法控制步进。同时,我看到请求出来并通过Charles从服务器返回。这只是应用程序似乎没有得到响应,只是坐在那里。
所以,这是代码。谢谢你的帮助!
public SyncVO sync(String userId, long lastUpdate, boolean includeFetch) throws IOException {
SyncVO result = null;
String url = BASE_URL + "users/" + userId + "/sync" + "?" + "fetch=" + includeFetch;
if (lastUpdate > 0) {
url += "&updatedSince=" + lastUpdate;
}
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("Accept-Encoding", "gzip");
httpGet.setHeader(AUTHORIZATION, BEARER + " " + mOAuthToken);
httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, USER_AGENT_STRING);
httpclient.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
HttpResponse response = httpclient.execute(httpGet);
if (isUnauthorized(response)) {
APPLICATION.needReauthentication();
return null;
}
if (response != null) {
InputStream stream = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
stream = new GZIPInputStream(stream);
}
InputStreamReader inReader = new InputStreamReader(stream, "UTF-8");
JsonParser jp = mJsonFactory.createJsonParser(inReader);
result = getObjectMapper().readValue(jp, SyncVO.class);
}
return result;
}
private ObjectMapper getObjectMapper() {
return (new ObjectMapper()
.configure(Feature.AUTO_DETECT_FIELDS, true)
.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true));
}
答案 0 :(得分:4)
不要忘记在每次请求后使用实体内容。
HttpEntity entity = response.getEntity();
try {
if (entity != null)
entity.consumeContent();
} catch (IOException e) {
e.printStackTrace();
}
答案 1 :(得分:1)
你绝对应该使用连接超时和套接字读取,并为服务器的最坏情况做好准备。网络操作永远不会100%可预测,客户端无法做到这一点,因此请确保您以最佳方式编码。
httpParameters = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 5000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
您也可以使用asyncTask.cancel(true);
取消任务答案 2 :(得分:1)
原因是因为您已将stream
打开。因此,response
处于不确定状态。这意味着您的全局变量httpClient
也处于不稳定状态,并且在重新使用客户端时无法获得新实体。
完成流后,您应该致电close()
。
stream.close();
答案 3 :(得分:-1)
网络调用需要一段时间,并会阻止UI线程。与您的jackson反序列化代码相同。这个东西需要放在一个单独的线程上。请参阅AsyncTask以获得简单的方法。