我正在尝试获取一个http响应字符串(只是一个JSON对象),有时候这段代码会等待无限时间
可能是,这种行为的原因是互联网连接不好(我使用3G调制解调器),但我需要一个稳定的解决方案来避免这种无限锁定。这可以做些什么来避免它?
line = reader.readLine()
HttpResponse response = httpClient.execute(httpPost);
InputStream content = null;
JSONObject json_obj;
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
try {
content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content, "UTF-8"), 256);
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {}
}
答案 0 :(得分:1)
您可以指定读取超时:
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000);
应将读取超时设置为30秒。 您可能还想指定连接超时:
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
答案 1 :(得分:0)
readLine()
或者任何网络/ IO应该在后台线程中完成,以防止锁定主线程。
如果您在Android 4.0+上测试代码,您还会看到主线程上不再允许网络连接,并会抛出异常。
看一下AsyncTask,这是一种在后台线程上运行此类任务的简单,轻松的方法。
答案 2 :(得分:0)
避免“无限”锁定的一个好方法是在单独的线程中执行此http调用,并使用处理程序,通知主线程信息已加载并可以按照您的意愿使用它。
这里也是我自己使用SaxParser的一个例子:
public void SearchFromSuperClass(String text)
{
mHandler = new Handler();
Thread t = new Thread(){
public void run() {
try {
String strurl="URLTOPATH";
URL url = new URL(strurl);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
FundsHandlerRanking handler = new FundsHandlerRanking();
parser.parse(url.openConnection().getInputStream(), handler);
search_response = handler.getrankings();
mHandler.post(mUpdateResults);
} catch (Exception e) {
search_response = null;
mHandler.post(mUpdateResults);
}
}
};
t.start();
}
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
private void updateResultsInUi() {
try
{
if(search_response != null)
{
lview.setAdapter(new SearchRankingAdapter(mycontext, search_response, false));
}
Pdialog.dismiss();
}
catch (Exception e) {
lview.setAdapter(null);
if (Pdialog.isShowing())
{
Pdialog.dismiss();
}
}
}
使用mHandler.post(...)将调用放入队列中以发送到主UI线程,在那里,您可以毫无问题地修改UI对象(不能修改主线程外的UI对象)
希望这有帮助