简体   繁体   English

BufferedReader.readLine()会阻塞一段时间

[英]BufferedReader.readLine() blocks for a while

I am trying to get a String of http response (just a JSON object), and sometimes this piece of code waits infinite time in 我正在尝试获取http响应的字符串(只是一个JSON对象),有时这段代码等待无限时间

line = reader.readLine()

May be, the reason of such behavior is bad Internet connection (I use 3G modem), but I need a stable solution to avoid this infinite lock. 可能是这种行为的原因是Internet连接不良(我使用3G调制解调器),但是我需要一个稳定的解决方案来避免这种无限锁定。 What can be done here to avoid it? 可以采取什么措施避免这种情况?

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

You can specify a read timeout: 您可以指定读取超时:

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

Should set a read timeout to 30 seconds. 应该将读取超时设置为30秒。 Probably, you also want to specify a connection timeout: 可能还需要指定连接超时:

client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
readLine()

Or any network/IO should be done in a background thread to prevent locking of the main thread. 否则任何网络/ IO都应在后台线程中完成,以防止主线程被锁定。

If you test your code on Android 4.0+ you'll also see that networking is no longer allowed on the main thread and will throw an exception. 如果您在Android 4.0+上测试代码,您还将看到主线程不再允许联网,并且将引发异常。

Take a look at AsyncTask which is a simple, painless way of running such tasks on a background thread. 看一下AsyncTask ,它是在后台线程上运行此类任务的一种简单而轻松的方法。

A good solution to avoid the "infinite" lock is to do this http calls in a separate thread, and with a Handler, notice to the main thread that the info is loaded and can use it like you want. 避免“无限”锁定的一个好的解决方案是在一个单独的线程中进行此http调用,并使用Handler通知主线程该信息已加载并可以按需要使用它。

Here an example of my own using a SaxParser too: 这也是我自己也使用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();
        }
    }
}

With mHandler.post(...) you put the call in the queue to be sended to the main UI thread, and there, you can modify UI objects without problem (CAN'T modify UI objects outside the Main thread). 使用mHandler.post(...),可以将调用放入要发送到主UI线程的队列中,在那里,您可以毫无问题地修改UI对象(不能在Main线程之外修改UI对象)。

Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM