[Android]为什么不能在没开looper的子线程中使用AsyncHttpClient

没开looper的子线程中使用AsyncHttpClient会出现下面的异常:
Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.

通过翻阅源码,发现AsyncHttpClient的请求最终会被提交到线程池中运行,那么就奇怪了,为什么不能在没开looper的子线程中运行呢?
上源码:
请求最终会调用AsyncHttpClientsendRequest方法

protected RequestHandle sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, ResponseHandlerInterface responseHandler, Context context) {
        if (uriRequest == null) {
            throw new IllegalArgumentException("HttpUriRequest must not be null");
        } else if (responseHandler == null) {
            throw new IllegalArgumentException("ResponseHandler must not be null");
        } else if (responseHandler.getUseSynchronousMode() && !responseHandler.getUsePoolThread()) {
            throw new IllegalArgumentException("Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.");
        } else {
            if (contentType != null) {
                if (uriRequest instanceof HttpEntityEnclosingRequestBase && ((HttpEntityEnclosingRequestBase)uriRequest).getEntity() != null && uriRequest.containsHeader("Content-Type")) {
                    log.w("AsyncHttpClient", "Passed contentType will be ignored because HttpEntity sets content type");
                } else {
                    uriRequest.setHeader("Content-Type", contentType);
                }
            }

            responseHandler.setRequestHeaders(uriRequest.getAllHeaders());
            responseHandler.setRequestURI(uriRequest.getURI());
            AsyncHttpRequest request = this.newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context);
            this.threadPool.submit(request);
            RequestHandle requestHandle = new RequestHandle(request);
            if (context != null) {
                Map var10 = this.requestMap;
                List requestList;
                synchronized(this.requestMap) {
                    requestList = (List)this.requestMap.get(context);
                    if (requestList == null) {
                        requestList = Collections.synchronizedList(new LinkedList());
                        this.requestMap.put(context, requestList);
                    }
                }

                requestList.add(requestHandle);
                Iterator iterator = requestList.iterator();

                while(iterator.hasNext()) {
                    if (((RequestHandle)iterator.next()).shouldBeGarbageCollected()) {
                        iterator.remove();
                    }
                }
            }

            return requestHandle;
        }
    }

在方法中可以看到这么一句话

 AsyncHttpRequest request = this.newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context);
            this.threadPool.submit(request);

所以可以断定会被提交到线程池中,而报错的原因是下面这句话:

else if (responseHandler.getUseSynchronousMode() && !responseHandler.getUsePoolThread()) {
            throw new IllegalArgumentException("Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.");

responseHandler是一个接口,具体实现类是AsyncHttpResponseHandler,这是一个基类,下面有很多子类
而在AsyncHttpResponseHandler类中有一个setUseSynchronousMode方法了一个setUsePoolThread方法

public void setUseSynchronousMode(boolean sync) {
        if (!sync && this.looper == null) {
            sync = true;
            AsyncHttpClient.log.w("AsyncHttpRH", "Current thread has not called Looper.prepare(). Forcing synchronous mode.");
        }

        if (!sync && this.handler == null) {
            this.handler = new AsyncHttpResponseHandler.ResponderHandler(this, this.looper);
        } else if (sync && this.handler != null) {
            this.handler = null;
        }

        this.useSynchronousMode = sync;
    }
public void setUsePoolThread(boolean pool) {
        if (pool) {
            this.looper = null;
            this.handler = null;
        }

        this.usePoolThread = pool;
    }

而在AsyncHttpResponseHandler类中的构造方法中,这两个属性全部被设置为false,在setUseSynchronousMode法中

if (!sync && this.looper == null) {
            sync = true;
            AsyncHttpClient.log.w("AsyncHttpRH", "Current thread has not called Looper.prepare(). Forcing synchronous mode.");
        }

          /*something*/

 this.useSynchronousMode = sync;

因为子线程没有looper,所以useSynchronousMode会被设置为true,
所以会报上面的异常,而在主线程中,因为主线程默认开启了looper所以不会报异常,至于looper干嘛用的,个人猜测,内部使用looper配合handler做了某些同步操作。

你可能感兴趣的:([Android]为什么不能在没开looper的子线程中使用AsyncHttpClient)