开发者

Android. Avoiding ANR with HttpClient

I have some problems with my app. In market reports often appears ANR repostr with HttpClient errors. There are

java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2016) at 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) at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:175) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:325) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:580) at org.apache.http.impl.client.开发者_StackOverflow中文版AbstractHttpClient.execute(AbstractHttpClient.java:512) at 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) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574) at java.lang.Thread.run(Thread.java:1020)


DALVIK THREADS: (mutexes: 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) at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:357) at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:207) at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:440) at java.net.Socket.connect(Socket.java:1013) at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143) at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465

There are any approach to avoid this errors? Maybe some best practice how to work with httpClient? In my app I am 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();
}

}

then in code I am useing following

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


You are probably calling that last snippet from the main UI thread in your Activity. If so, you should consider performing a potentially high latency operation like HttpClient.execute in another thread. You can either simply use another Thread or an Executor.

If you need to coordinate the network request with the UI, try AsyncTask or Loaders.


The problem was that I not read entire response body . I just only check response is null or not if I expected boolean result. You must read response body in any case and and close response stream before next call of http client instance. For example

  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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜