序言
我们可能已经使用过Volley,当然现在最多得回事OkHttp,Volley的实现也是之前相当大的一部分网络请求框架的大致实现方式。如果你已经饱读各类网络请求库的源代码,可以移步了,这里只是对于其大致面貌进行一个阐述,附带上一些代码的实现,具体的将会写好之后贴出来。
正题
Request
Response
HttpStack
NetWorkExecutor
ResponseDelivery
HttpStackFactory
RequestQueue
一个网络请求框架,大致需要自己写这些类,具体做什么呢?
要有一个Request类,如果是要写框架,当然要将其声明为抽象类或接口,方便进一步扩展,其要实现的功能是对于底层的HttpUrlConnection或者HttpClient进行一个封装,比如对于头部和一些请求参数的设定,用户可以很方便的对其定制,然后将参数的设置细节进行一个隐藏,然后用户可以很方便的进行参数的传递,同时设置请求的回调,直接在UI线程处理结果,要借助ResponseDelivery来实现。
维护一个请求队列,我们的请求会有很多,这个时候,我们需要维护一个线程安全的请求队列,然后根据请求的优先级,来进行相应的操作。
-
请求队列构建好了,那么接下来需要的就是有执行者来进行执行这些操作了,显然为了提升速度,我们需要通过线程池,线程池中的线程用来出列这些请求,如果出列请求呢?显然,轮询请求队列即可,当然如果我们设置了缓存,可以先根据请求的url在我们的cache中进行一个查找,如果找不到的时候,可以再发起网络请求,得到轮询队列这种的请求,具体的任务就要交给负责网络请求的类去做了。这里我们通过一个Http栈,就是对于HttpClient和HttpUrlConnection的一个封装,然后对我们的请求进行一个解析,然后返回结果。
public void run(){ try { while(!isStop){ final Request<?> request = mRequestQueue.take(); if(request.isCanceled()){ continue; } Response response = null; if(isUseCache(request)){ response = mReqCache.get(request.getUrl()); }else{ response = mHttpStack.preformRequest(request); if(request.isShouldCache()&&isSuccess(response)){ mReqCache.put(request.getUrl(),response); } } mResponseDelivery.deliveryResponse(request,response); } }catch (InterruptedException e){ } }
public interface HttpStack { public Response preformRequest(Request<?> request); }
返回的结果封装在一个Response中,我们可以根据我们的需求,对其做相应的解析。
结果传递,拿到了我们的相应结果我们现在处在线程池中,是无法对于我们的UI线程进行相应的操作的,因此我们需要将我们的结果传递到主线程。通过我们的自己实现ResponseDelivery,具体的实现就是得到了结果后,我们注入我们的请求类和我们的响应结果依赖,该类会获得当前主线程的Handler,然后实现一个runnable,调用Request的监听器,通知将Response传递进去,然后让Handler,post出这个Runnable,优雅实现,线程切换。
public class ResponseDelivery implements Executor {
Handler mResponseHandler = new Handler(Looper.getMainLooper());
public void deliveryResponse(final Request<?> request,final Response response){
Runnable respRunnable = new Runnable() {
@Override
public void run() {
request.deliveryResponse(response);
}
};
execute(respRunnable);
}
@Override
public void execute(Runnable command) {
mResponseHandler.post(command);
}
Request类中用来传递的函数
public final void deliveryResponse(Response response){
T result = parseResponse(response);
if(mRequestListener!=null){
int stCode = response!=null?response.getStatusCode():-1;
String msg = response !=null?response.getMessage():"unkown error";
mRequestListener.onComplete(stCode,result,msg);
}
}
感兴趣的话,开始动手撸吧。。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。