Android. Как избежать ANR с помощью HttpClient - PullRequest
2 голосов
/ 13 октября 2011

У меня проблемы с приложением. В обзорах рынка часто появляется репортр ANR с ошибками HttpClient. Есть

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) в 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.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) в java.util.concurrent.LinkedBlockingQueue.take (LinkedBlockingQueue.java:413) в java.util.concurrent.ThreadPoolExecutor.getTask (ThreadPoolExecutor.java:1014) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1074) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:574) at java.lang.Thread.run (Thread.java:1020)


DALVIK РЕЗЬБЫ: (мьютексы: tll = 0 tsl = 0 tscl = 0 ghl = 0 hwl = 0 hwll = 0) "основной" prio = 5 тид = 1 нативный | group = "main" sCount = 1 dsCount = 0 obj = 0x40027550 self = 0xcfc0 | sysTid = 2557 nice = 0 sched = 0/0 cgrp = дескриптор по умолчанию = -1345006240 | schedstat = (6440246597 181026702867 12047) в org.apache.harmony.luni.platform.OSNetworkSystem.connect (собственный метод) at 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) в org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection (DefaultClientConnectionOperator.java:143) в org.apache.http.impl.conn.AbstractPoolEntry.open (AbstractPoolEntry.java:164) at 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 голосов
/ 23 августа 2012

Проблема заключалась в том, что я не прочитал весь текст ответа. Я только проверяю, является ли ответ нулевым или нет, если я ожидал логического результата. В любом случае вы должны прочитать тело ответа и закрыть поток ответов перед следующим вызовом экземпляра 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 голосов
/ 13 октября 2011

Вы, вероятно, вызываете этот последний фрагмент из основного потока пользовательского интерфейса в своей деятельности.Если это так, вам следует рассмотреть возможность выполнения операции с потенциально высокой задержкой, такой как HttpClient.execute, в другом потоке.Вы можете просто использовать другой поток или исполнителя.

Если вам нужно согласовать сетевой запрос с пользовательским интерфейсом, попробуйте AsyncTask или Loaders .

...