2012-11-06 29 views
0

我试图让HTTP响应(只是一个JSON对象)的字符串,有时候这段代码无限的等待时间BufferedReader.readLine()块一会儿

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

当你想杀死一切 – fiddler

+2

为什么(也是最重要的是如何),你可以做'的readLine()'的东西,在一个单独的线程,并关闭读者,你会考虑避免网络查询是非阻塞? (也EntityUtils.toString做你在1行) – njzk2

+0

@fiddler我已经在后台线程中做到了这一点,问题只是关于阻塞。 – Prizoff

回答

1

您可以指定读取超时:

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

应该读超时设置为30秒。 也许,你也想指定连接超时:

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

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

如果您在Android 4.0+上测试您的代码,您还会看到主线程不再允许网络连接,并且会抛出异常。

看看AsyncTask这是一种在后台线程上运行此类任务的简单而无痛的方式。

+0

我已经在后台线程中做到了这一点,问题只是关于阻塞。 – Prizoff

+0

我看,超时肯定是正确的答案。 – Guykun

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(...)你把呼叫在队列中sended到主UI线程,并在那里,您可以毫无问题地修改UI对象(不能修改主线程外的UI对象)。

希望这有助于

+0

有一个很好的选项把超时作为http调用参数 – Neonamu