Volley框架的基本解读(六)

接上一遍内容,我们继续解析,来揭开mDelivery的神秘面纱,它的类是ResponseDelivery,来看源码:


public interface ResponseDelivery {
    /**
     * Parses a response from the network or cache and delivers it.
     */
    public void postResponse(Request<?> request, Response<?> response);

    /**
     * Parses a response from the network or cache and delivers it. The provided
     * Runnable will be executed after delivery.
     */
    public void postResponse(Request<?> request, Response<?> response, Runnable runnable);

    /**
     * Posts an error for the given request.
     */
    public void postError(Request<?> request, VolleyError error);
}


这里接口,里面有三个方法,分别用于分发正确结果,分发正确结果并执行Runnable,分发错误结果。


实例的创建是在RequestQueue的构造方法中


public RequestQueue(Cache cache, Network network, int threadPoolSize) {
        this(cache, network, threadPoolSize,
                new ExecutorDelivery(new Handler(Looper.getMainLooper())));
    }

那么我们先从ExecutorDelivery的构造方法看起


public ExecutorDelivery(final Handler handler) {
        // Make an Executor that just wraps the handler.
        mResponsePoster = new Executor() {
            @Override
            public void execute(Runnable command) {
                handler.post(command);
            }
        };
    }

代码很清晰,只是执行了handler.post方法,ResponseDelivery接口抽象方法的复写


@Override
    public void postResponse(Request<?> request, Response<?> response) {
        postResponse(request, response, null);
    }

继续看


@Override
    public void postResponse(Request<?> request, Response<?> response, Runnable runnable) {
        request.markDelivered();
        request.addMarker("post-response");
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable));
    }

仅有三句代码,分别是标记分发事件完毕,调试信息,执行一个Runnable,ResponseDeliveryRunnable就是Runnable,看源码


private class ResponseDeliveryRunnable implements Runnable

看run方法


@SuppressWarnings("unchecked")
        @Override
        public void run() {
            // If this request has canceled, finish it and don't deliver.
        	// 如果该request已经取消,则停止分发
            if (mRequest.isCanceled()) {
                mRequest.finish("canceled-at-delivery");
                return;
            }

            // Deliver a normal response or error, depending.
            if (mResponse.isSuccess()) {
                mRequest.deliverResponse(mResponse.result);
            } else {
                mRequest.deliverError(mResponse.error);
            }

            // If this is an intermediate response, add a marker, otherwise we're done
            // and the request can be finished.
            if (mResponse.intermediate) {
                mRequest.addMarker("intermediate-response");
            } else {
                mRequest.finish("done");
            }

            // If we have been provided a post-delivery runnable, run it.
            if (mRunnable != null) {
                mRunnable.run();
            }
       }

判断request是否取消,这段代码已经出现多次了,在判断请求是否成功,我们点进去看看


/**
     * Returns whether this response is considered successful.
     * 
     * 是否成功
     */
    public boolean isSuccess() {
        return error == null;
    }

error就是VolleyError,在网络请求的时候我们说过,仅有两种方式可以跳出循环,要么请求成功,要么抛出异常,先说请求成功BasicNetwork将服务器返回信息封装成NetworkResponse给予返回,NetworkDispatcher有这样一句代码对它进行解析:


// 交由Request进行解析Response
                Response<?> response = request.parseNetworkResponse(networkResponse);

parseNetworkResponse是定义在request中的抽象方法,我们找一个具体子类看看,StringRequest的源码:


@Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        try {
            parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            parsed = new String(response.data);
        }
        return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
    }

HttpHeaderParser.parseCharset(response.headers)是从请求头中找出编码格式,绝大多数结果都是UTF-8,重点在return的这段代码,HttpHeaderParser.parseCacheHeaders(response)意思是从response中解析出一个实体。


/** 
     * Returns a successful response containing the parsed result. 
     * 
     * 成功
     */
    public static <T> Response<T> success(T result, Cache.Entry cacheEntry) {
        return new Response<T>(result, cacheEntry);
    }

private Response(T result, Cache.Entry cacheEntry) {
        this.result = result;
        this.cacheEntry = cacheEntry;
        this.error = null;
    }

看到重点了吗?this.error = null,成功error就是null。


思路回到BasicNetwork如果抛出异常,NetworkDispatcher调用这段代码:


mDelivery.postError(request, new VolleyError(e));

看ExecutorDelivery的具体实现


@Override
    public void postError(Request<?> request, VolleyError error) {
        request.addMarker("post-error");
        Response<?> response = Response.error(error);
        mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null));
    }

重点来了,Response<?> response = Response.error(error);上代码:


/**
     * Returns a failed response containing the given error code and an optional
     * localized message displayed to the user.
     * 
     * 失败
     */
    public static <T> Response<T> error(VolleyError error) {
        return new Response<T>(error);
    }

private Response(VolleyError error) {
        this.result = null;
        this.cacheEntry = null;
        this.error = error;
    }

看到了吧,this.error = error,失败error不为null。


mResponse.isSuccess()就可以做出正确的判断,request调用deliverResponse分发结果,这也是一个抽象方法,在拿StringRequest的实现看看:


@Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }

mListener这就是我们给的成功回调


deliverError是定义在request的方法


public void deliverError(VolleyError error) {
        if (mErrorListener != null) {
            mErrorListener.onErrorResponse(error);
        }
    }


mErrorListener正是错误回调


接着主线走,mResponse.intermediate是命中过期缓存标志,是打出调试信息,否结束request,最后mRunnable不为null,给予执行。


万象森罗,不离两仪所育;百法纷凑,无越三教之境。


至此Volley主线以全部走通,后面会单独解析Request与Response这两个重中之重。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值