Android. 使用HttpClient避免ANR(应用程序无响应)问题

37 浏览
0 Comments

Android. 使用HttpClient避免ANR(应用程序无响应)问题

我的应用程序有一些问题。
市场报告经常出现HttpClient错误的ANR报告。以下是:

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线程:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" 优先级=5 tid=1 本地线程
| 组="main" sCount=1 dsCount=0 obj=0x40027550 自身=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

有没有避免这些错误的方法?也许有一些最佳实践,如何使用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();

0
0 Comments

\n\n问题是我没有读取完整的响应体。如果我预期的是布尔值结果,我只会检查响应是否为null。您必须在任何情况下读取响应体,并在Http客户端实例的下一次调用之前关闭响应流。例如\n

  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
0 Comments

你可能正在你的Activity的主UI线程中调用最后一个代码片段。如果是这样,你应该考虑在另一个线程中执行可能具有高延迟的操作,例如HttpClient.execute。你可以使用另一个线程或执行器。

如果你需要将网络请求与UI协调,可以尝试使用AsyncTaskLoaders

0