Volley框架的基本解读(七)

在前面六篇博客中,我们已经将Volley框架主线全部走完,今天我们来讲讲Volley框架中两个十分重要的角色Request与Response,这两个类之所以放到最后来讲,一方面对Volley没有一个清晰的认识,可能会比较难懂,另方面好戏不都是压轴的吗?


我们先看Request的源码:


public abstract class Request<T> implements Comparable<Request<T>>

它是一个抽象类,并实现了Comparable用于比较排序,还记得RequestQueue中的mCacheQueue与mNetworkQueue这两个优先级队列吗?实现Comparable接口就是为了能在队列中排序,而从实现某些Request的优先请求。


我们还有先从构造方法开始看起:


public Request(String url, Response.ErrorListener listener) {
        this(Method.DEPRECATED_GET_OR_POST, url, listener);
    }

这个构造方法有两个参数,分别是URL与错误回调,它调用了另一个构造方法,Method是Request的一个内部接口,我们看看:


/**
     * Supported request methods.
     * 支持的请求方式
     */
    public interface Method {
        int DEPRECATED_GET_OR_POST = -1;
        int GET = 0;
        int POST = 1;
        int PUT = 2;
        int DELETE = 3;
    }

可见内部定义了四种支持的请求方式,DEPRECATED_GET_OR_POST这个大家可以无视,我也不是很理解,接着看:


public Request(int method, String url, Response.ErrorListener listener) {
        mMethod = method;
        mUrl = url;
        mErrorListener = listener;
        setRetryPolicy(new DefaultRetryPolicy());

        mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();
    }

这里为我们创建了一个重试策略并绑定在request中,mDefaultTrafficStatsTag是用于流量监控的唯一标识,通过URL产生。


Request内部定义了很多公共方法,比较重要的有这么几个,我们一起来看看:


/**
     * Returns true if this request has been canceled.
     * 
     * 是否取消该request
     */
    public boolean isCanceled() {
        return mCanceled;
    }

/**
     * Mark this request as canceled.  No callback will be delivered.
     * 取消请求
     */
    public void cancel() {
        mCanceled = true;
    }

在之前的源码解析中我们经常可以看到isCanceled,现在我们知道它仅仅只是做了一个标识而已。


/**
     * Returns the cache key for this request.  By default, this is the URL.
     * 获取缓存的Key,就是URL
     */
    public String getCacheKey() {
        return getUrl();
    }

/**
     * Returns the URL of this request.
     * 请求URL
     */
    public String getUrl() {
        return mUrl;
    }

getCacheKey该方法在缓存解析的时候出现过,缓存的Key就是URL。


/**
     * Returns a Map of parameters to be used for a POST or PUT request.  Can throw
     * {@link AuthFailureError} as authentication may be required to provide these values.
     *
     * <p>Note that you can directly override {@link #getBody()} for custom data.</p>
     *
     * @throws AuthFailureError in the event of auth failure
     * 
     * 空请求体,子类可以复写该方法,如果子类需要的话
     */
    protected Map<String, String> getParams() throws AuthFailureError {
        return null;
    }


public byte[] getBody() throws AuthFailureError {
        Map<String, String> params = getParams();
        if (params != null && params.size() > 0) {
            return encodeParameters(params, getParamsEncoding());
        }
        return null;
    }

private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
        StringBuilder encodedParams = new StringBuilder();
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
                encodedParams.append('=');
                encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
                encodedParams.append('&');
            }
            return encodedParams.toString().getBytes(paramsEncoding);
        } catch (UnsupportedEncodingException uee) {
            throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
        }
    }


该方法用于POST请求,添加请求体。


/**
     * Priority values.  Requests will be processed from higher priorities to
     * lower priorities, in FIFO order.
     * 
     * 优先级
     */
    public enum Priority {
        LOW,
        NORMAL,
        HIGH,
        IMMEDIATE
    }

/**
     * Returns the {@link Priority} of this request; {@link Priority#NORMAL} by default.
     * 
     * 获取优先级,默认正常
     */
    public Priority getPriority() {
        return Priority.NORMAL;
    }

Request的优先级,当你有急切请求需求的时候,就可以设置它。


/**
     * Mark this request as having a response delivered on it.  This can be used
     * later in the request's lifetime for suppressing identical responses.
     * 
     * 标记分发事件完毕
     */
    public void markDelivered() {
        mResponseDelivered = true;
    }

它同样是以个标记。


@Override
    public int compareTo(Request<T> other) {
        Priority left = this.getPriority();
        Priority right = other.getPriority();

        // High-priority requests are "lesser" so they are sorted to the front.
        // Equal priorities are sorted by sequence number to provide FIFO ordering.
        // 如果优先级相等,按序列号排序,序列号高则放在后面
        return left == right ?
                this.mSequence - other.mSequence :
                right.ordinal() - left.ordinal();
    }

这里是重点,request的比较,优先级优先,如果优先级相同,再比较序列号,序列号由RequestQueue中AtomicInteger类,我们调用add方法时生成并绑定在request中,AtomicInteger的incrementAndGet方法可以生成单调递增的序列号。


/**
     * Gets a sequence number.
     * 
     * 生成单调递增的序列号
     */
    public int getSequenceNumber() {
        return mSequenceGenerator.incrementAndGet();
    }

Request有两个抽象方法,


/**
     * Subclasses must implement this to parse the raw network response
     * and return an appropriate response type. This method will be
     * called from a worker thread.  The response will not be delivered
     * if you return null.
     * @param response Response from the network
     * @return The parsed response, or null in the case of an error
     * 
     * 解析response
     */
    abstract protected Response<T> parseNetworkResponse(NetworkResponse response);


/**
     * Subclasses must implement this to perform delivery of the parsed
     * response to their listeners.  The given response is guaranteed to
     * be non-null; responses that fail to parse are not delivered.
     * @param response The parsed response returned by
     * {@link #parseNetworkResponse(NetworkResponse)}
     * 
     * 分发Response
     */
    abstract protected void deliverResponse(T response);

在说之前,我找个具体子类先看看,依然还是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));
    }


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


一目了然,deliverResponse就是负责成功回调,因为在request只定义了公共的错误回调,成功回调交由子类自己去实现,而parseNetworkResponse则负责解析NetworkResponse,每个不同的子类解析出不同的返回类型,如这里的String,值得一提的是,这个方法之所以会定义在Request中是因为Request的泛型,只有Request知道它请求想让Response返回的是什么。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值