0

我正在尝试获取一个 http 响应字符串(只是一个 JSON 对象),有时这段代码会等待无限时间

line = reader.readLine()

可能是,这种行为的原因是互联网连接不好(我使用 3G 调制解调器),但我需要一个稳定的解决方案来避免这种无限锁定。在这里可以做些什么来避免它?

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) {}
}
4

3 回答 3

1

您可以指定读取超时:

HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000);

应将读取超时设置为 30 秒。可能,您还想指定连接超时:

client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
于 2012-11-06T16:09:10.457 回答
0
readLine()

或者任何网络/IO 都应该在后台线程中完成,以防止锁定主线程。

如果您在 Android 4.0+ 上测试您的代码,您还会看到主线程上不再允许联网,并且会引发异常。

看看AsyncTask,它是一种在后台线程上运行此类任务的简单、轻松的方式。

于 2012-11-06T16:11:03.983 回答
0

避免“无限”锁定的一个很好的解决方案是在单独的线程中执行此 http 调用,并使用 Handler 通知主线程该信息已加载并且可以根据需要使用它。

这是我自己使用 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 对象)。

希望这可以帮助

于 2012-11-06T16:15:28.373 回答