Android系统。用HttpClient避免ANR

时间:2011-10-13 12:21:38

标签: android error-handling httpclient android-anr-dialog

我的应用有些问题。 在市场报告中经常会出现带有HttpClient错误的ANR repostr。有

  

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


  

java.util.concurrent.locks.AbstractQueuedSynchronizer中$ ConditionObject.await(AbstractQueuedSynchronizer.java:2022)     at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)     at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1014)     在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1074)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:574)     在java.lang.Thread.run(Thread.java:1020)

     
     

DALVIK THREADS:   (互斥:tll = 0 tsl = 0 tscl = 0 ghl = 0 hwl = 0 hwll = 0)   “main”prio = 5 tid = 1 NATIVE     | group =“main”sCount = 1 dsCount = 0 obj = 0x40027550 self = 0xcfc0     | sysTid = 2557 nice = 0 sched = 0/0 cgrp = default handle = -1345006240     | schedstat =(6440246597 181026702867 12047)     at org.apache.harmony.luni.platform.OSNetworkSystem.connect(Native Method)     在dalvik.system.BlockGuard $ WrappedNetworkSystem.connect(BlockGuard.java:357)     在org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:207)     在org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:440)     在java.net.Socket.connect(Socket.java:1013)     在org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)     在org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)     在org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)     在org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)     在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?在我的应用程序中,我很高兴:

 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();

2 个答案:

答案 0 :(得分:0)

您可能正在调用Activity中主UI线程的最后一个片段。如果是这样,您应该考虑在另一个线程中执行像HttpClient.execute这样的潜在高延迟操作。您可以简单地使用另一个Thread或Executor。

如果您需要使用界面来协调网络请求,请尝试AsyncTaskLoaders

答案 1 :(得分:0)

问题在于我没有阅读整个回复正文。我只是检查响应是否为null,如果我期望布尔结果。您必须在任何情况下读取响应正文,并在下次调用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();
    }