2011-10-13 76 views
1

我的應用程序出現了一些問題。 在市場報告中經常會出現ANR與HttpClient錯誤的地址。有Android。使用HttpClient避免ANR

java.util.concurrent.locks.AbstractQueuedSynchronizer中的$ ConditionObject.await(AbstractQueuedSynchronizer.java:2016) 在org.apache.http.impl.conn.tsccm.WaitingThread.await(WaitingThread.java: 159) at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:339) at org.apache.http.impl.conn.tsccm.ConnPoolByRoute $ 1.getPoolEntry(ConnPoolByRoute.java:238 ) 在org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager $ 1.getConnection(ThreadSafeClientConnManager.java:175) 在org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:325) 在org.apache.http.imp l.client.AbstractHttpClient.execute(AbstractHttpClient.java:580) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:512) at org.apache.http.impl.client.AbstractHttpClient。執行(AbstractHttpClient.java:490)


java.util.concurrent.locks.AbstractQueuedSynchronizer中的$ ConditionObject.await(AbstractQueuedSynchronizer.java:2022) 在java.util.concurrent.LinkedBlockingQueue.take (LinkedBlockingQueue.java:413) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1014)(ThreadPoolExecutor.java:574) at java.lang.Thread.run(Thread。)在線程序,請參閱java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:574)的java:1020)


DALVIK線程: (互斥:TLL = 0 TSL = 0 TSCL = 0 GHL = 0 HWL = 0 hwll = 0) 「主」 PRIO = 5 TID = 1 NATIVE | group =「main」sCount = 1 dsCount = 0 obj = 0x40027550 self = 0xcfc0 | sysTid = 2557 nice = 0 sched = 0/0 cgrp =默認句柄= -1345006240 | schedstat =(6440246597 181026702867 12047) at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method) at dalvik.system.BlockGuard $ WrappedNetworkSystem.connect(BlockGuard.java:357) at org.apache。在java.net.Socket.connect(Socket。)上的org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:440) 。的java:1013) 在org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119) 在org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143) 在org.a提供org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) (org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359) at org.apache.http.impl。 client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 在org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 在org.apache.http.impl.client.AbstractHttpClient.execute( AbstractHttpClient.java:465

有什麼辦法可以避免這個錯誤?也許一些最佳實踐如何使用httpClient?在我的應用我usung:

public ApiImpl() { 
    this.httpClient = new DefaultHttpClient(); 
    ClientConnectionManager mgr = httpClient.getConnectionManager(); 
    HttpParams params = httpClient.getParams(); 
    this.httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, mgr.getSchemeRegistry()), params); 
} 


public class Client { 

private static Api api; 
private static Client instance = null; 


public static Client getInstance() { 
    if (instance == null) { 
     instance = new Client(); 
    } 
    return instance; 
} 

private Client() { 
    api = new ApiImpl(); 
} 

}

然後在代碼中,我期運用以下

Client client = Client.getInstance(); 
client.do(); 
+0

它會在getInstance()調用還是執行http請求時報告anr? – Blackbelt

+0

當我調用execute() –

+0

那是因爲httpclient執行調用,是一個阻塞調用。由於延遲執行,UI線程似乎被阻塞。你需要運行執行,並在一個單獨的線程或異步任務中的每個阻塞調用 – Blackbelt

回答

0

的問題是,我沒有看過整個響應體。我只是檢查響應是否爲空,如果我期望布爾結果。您必須在任何情況下閱讀響應主體,並在下一次呼叫http客戶端實例之前關閉響應流。例如

InputStream stream = response.getEntity().getContent(); 

    private String streamToString(InputStream is) { 
     if (is == null) return null; 
     BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     try { 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       is.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return sb.toString(); 
    } 
0

你可能會調用從主UI線程,去年片段在你的活動。如果是這樣,您應該考慮在另一個線程中執行潛在的高延遲操作,如HttpClient.execute。您可以簡單地使用另一個線程或執行程序。

如果您需要使用UI協調網絡請求,請嘗試使用AsyncTaskLoaders

+0

不,我使用處理程序和可運行來執行請求。完成後,我將消息發送給主線程。打一次 - 一切正常,打電話 - 兩次 - 好的,打三次電話 - ANR。 –

+0

如果您在主線程上實例化處理程序,則您的執行Runnables仍在主線程上運行。處理程序只是一個消息隊列,它在實例化的同一個線程上運行。 – kramimus

+0

在其他線程中使用處理程序的正確方法是什麼?新的線程(myRunnable).start()而不是handler.post(myRunnable)對不對? –