2
votes

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.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();
2
does it report anr on the getInstance() call or when you execute an http request?Blackbelt
that's because that httpclient execute call, is a blocking call. The UI thread seems to be blocked because of the delay of the execute. You need to run the execute, and every blocking call in a separate thread or async taskBlackbelt
No, I am using handler and runnable to execute request. When it done I am sending message to main thread. Call once - everything ok, call - twice - ok, call thriceGeorgy Gobozov
Ok.. is the same http client shared among multiple thread or you have the main thread and your thread? in the latter try to use a simple default http client instead of the thread safe implementation and see if something changeBlackbelt

2 Answers

0
votes

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.

0
votes

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