AsyncHttpClient 源码分析
开源的AsyncHttp是基于Apache HTTP Client包装的一个库,比较简单,回调进行获取数据,不用自己处理线程和实例化Handler
上一篇写了个 AsyncHttpClient 获取图片和网页数据演示 简单用法
AsyncHttpClient.java 是暴露的接口,最主要的就是Post和Get 2种,还有其他的HTTP请求方式 比如还有Delete,Patch操作,不是很常用
线程池用的是 Executors.newCachedThreadPool() 这个源码里面显示 核心线程是0,创建的线程60秒后不用就销毁,感觉比较符合网络频繁操作一段时间,
比如ListView异步下载Bitmap图片
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
RequestHandle 返回的请求运行对象,可以cancel一个请求 ,但不一定能成功。
创建异步请求用于任务执行
protected AsyncHttpRequest newAsyncHttpRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, ResponseHandlerInterface responseHandler, Context context) { return new AsyncHttpRequest(client, httpContext, uriRequest, responseHandler); } //发送请求 protected RequestHandle sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, ResponseHandlerInterface responseHandler, Context context) { //判断代码省去。。。。。只看关键的 if (contentType != null) { if (uriRequest instanceof HttpEntityEnclosingRequestBase && ((HttpEntityEnclosingRequestBase) uriRequest).getEntity() != null) { Log.w(LOG_TAG, "Passed contentType will be ignored because HttpEntity sets content type"); } else { uriRequest.setHeader(HEADER_CONTENT_TYPE, contentType); } } responseHandler.setRequestHeaders(uriRequest.getAllHeaders()); responseHandler.setRequestURI(uriRequest.getURI()); //构造一个请求对象,线程运行 AsyncHttpRequest request = newAsyncHttpRequest(client, httpContext, uriRequest, contentType, responseHandler, context); threadPool.submit(request);//提交任务 RequestHandle requestHandle = new RequestHandle(request); //这个地方用来判断之前是否有请求,回收不必要的请求对象,因为RequestHandle可以取消任务,用的是Weak对象 if (context != null) { // Add request to request map List<RequestHandle> requestList = requestMap.get(context); synchronized (requestMap) { if (requestList == null) { requestList = Collections.synchronizedList(new LinkedList<RequestHandle>()); requestMap.put(context, requestList); } } requestList.add(requestHandle); Iterator<RequestHandle> iterator = requestList.iterator(); while (iterator.hasNext()) { if (iterator.next().shouldBeGarbageCollected()) { //清理不用的Weak对象 iterator.remove(); } } } return requestHandle; }
RequestHandle requestHandle = new RequestHandle(request);
ResponseHandlerInterface 回调接口定义了 任务的开始,过程,结束还有错误消息
UI消息在哪里发送? 在抽象类AsyncHttpResponseHandler构造函数里面
//UI线程里面的Handler实例化是在构造函数里面,默认就是myLooper,默认构造函数是传null的 public AsyncHttpResponseHandler(Looper looper) { this.looper = looper == null ? Looper.myLooper() : looper; // Use asynchronous mode by default.默认异步的 setUseSynchronousMode(false); // Do not use the pool's thread to fire callbacks by default. setUsePoolThread(false); } @Override public void setUseSynchronousMode(boolean sync) { // A looper must be prepared before setting asynchronous mode. if (!sync && looper == null) { sync = true; Log.w(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode."); } // If using asynchronous mode. if (!sync && handler == null) { // Create a handler on current thread to submit tasks handler = new ResponderHandler(this, looper);//初始化,看ResponderHandler } else if (sync && handler != null) { // TODO: Consider adding a flag to remove all queued messages. handler = null; } useSynchronousMode = sync; } private static class ResponderHandler extends Handler { private final AsyncHttpResponseHandler mResponder; ResponderHandler(AsyncHttpResponseHandler mResponder, Looper looper) { super(looper); this.mResponder = mResponder; } @Override public void handleMessage(Message msg) { mResponder.handleMessage(msg); //最终提交消息处理的地方 } }
AsyncHttpResponseHandler 的子类有多个,包括Binary,Text,JSON 回调
UML 简单的类图
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。