序言

我们可能已经使用过Volley,当然现在最多得回事OkHttp,Volley的实现也是之前相当大的一部分网络请求框架的大致实现方式。如果你已经饱读各类网络请求库的源代码,可以移步了,这里只是对于其大致面貌进行一个阐述,附带上一些代码的实现,具体的将会写好之后贴出来。

正题

  • Request

  • Response

  • HttpStack

  • NetWorkExecutor

  • ResponseDelivery

  • HttpStackFactory

  • RequestQueue
    一个网络请求框架,大致需要自己写这些类,具体做什么呢?

  1. 要有一个Request类,如果是要写框架,当然要将其声明为抽象类或接口,方便进一步扩展,其要实现的功能是对于底层的HttpUrlConnection或者HttpClient进行一个封装,比如对于头部和一些请求参数的设定,用户可以很方便的对其定制,然后将参数的设置细节进行一个隐藏,然后用户可以很方便的进行参数的传递,同时设置请求的回调,直接在UI线程处理结果,要借助ResponseDelivery来实现。

  2. 维护一个请求队列,我们的请求会有很多,这个时候,我们需要维护一个线程安全的请求队列,然后根据请求的优先级,来进行相应的操作。

  3. 请求队列构建好了,那么接下来需要的就是有执行者来进行执行这些操作了,显然为了提升速度,我们需要通过线程池,线程池中的线程用来出列这些请求,如果出列请求呢?显然,轮询请求队列即可,当然如果我们设置了缓存,可以先根据请求的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);
    }
  4. 返回的结果封装在一个Response中,我们可以根据我们的需求,对其做相应的解析。

  5. 结果传递,拿到了我们的相应结果我们现在处在线程池中,是无法对于我们的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);
        }
    }

感兴趣的话,开始动手撸吧。。


Jensen95
2.9k 声望534 粉丝

连续创业者。