码迷,mamicode.com
首页 > 其他好文 > 详细

volley 框架剖析(三) Request类精解

时间:2015-04-26 22:49:48      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:volley

Request是所有网络请求的基类,它实现了Comparable接口,前面提到RequestQueue可按照优先级队进行排序,这里的Comparable就是为优先级排序作准备。

接下来,我们对Request中比较重要或有趣的成员或方法进行一一解释。

Request中包括一个对支持的Http方法的定义。这里使用的内部接口而不是枚举来实现的。

 public interface Method {
        int DEPRECATED_GET_OR_POST = -1;
        int GET = 0;
        int POST = 1;
        int PUT = 2;
        int DELETE = 3;
        int HEAD = 4;
        int OPTIONS = 5;
        int TRACE = 6;
        int PATCH = 7;
    }

Volley的日志记录是相关完善的,在定义日志系的时候也有一个小技巧值得我们学习,即在创建对象的时候就判断需要不需要日志,如果不需要日志,则不创建。

private final MarkerLog mEventLog = MarkerLog.ENABLED ? new MarkerLog() : null;

mIdentifier是唯一标识符,它的生成是在构造函数中调用createIdentifier方法。其算法是由Http方法,URL,当前系统时间以及内部计数器串起来的字符串,然后计算的一个Sha1。
不过我觉得这里的算法不是线程安全的,有可能会产生相同的ID。

private String mIdentifier;
private static String createIdentifier(final int method, final String url) {
        return InternalUtils.sha1Hash("Request:" + method + ":" + url +
                ":" + System.currentTimeMillis() + ":" + (sCounter++));
}

一般网络都需要重试,这里它定义了 一个重试策略。

private RetryPolicy mRetryPolicy;

在volley的设计中这个重试策略的用法是如果抛出VolleyError则不再重试,否则,就会重试。这个重试的机制是由BasicNetwork中的while(true)这个死循环来处理。

它有一个默认实现类DefaultRetryPolicy,实现得比较简单,只是做了一个次数的重试,且只重试一次。但我们看到,DefaultRetryPolicy中还是埋下了一些伏笔。比如,后退因子mBackoffMultiplier,以及超时等待。也就是说,我们在丰富这个重试策略的时候,也可以做成等待多久后,再试一次。
比如下面的代码实现的就是在重试前先等待一段时间,再试。这一段时间就是由mCurrentTimeoutMs来决定。

/**
 * Created by Rex on 4/26/2015.
 */
public class WaitRetryPolicy extends DefaultRetryPolicy {

    @Override
    public void retry(VolleyError error) throws VolleyError {
        try {
            Thread.sleep(getCurrentTimeout());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        super.retry(error);
    }
}

此外,我们注意到有以几个成员:

   // A cheap variant of request tracing used to dump slow requests.
    private long mRequestBirthTime = 0;

    /** Threshold at which we should log the request (even when debug logging is not enabled). */
    private static final long SLOW_REQUEST_THRESHOLD_MS = 3000;

在finish方法中,有这么一段,

 long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
            if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
                VolleyLog.d("%d ms: %s", requestTime, this.toString());
            }

做什么用呢?当volley发现一个请求的开销超出某个阈值(SLOW_REQUEST_THRESHOLD_MS)时,则不管是不是log开关有没有打开,都会打印一个调试日志,用于尽快的跟踪问题。这个习惯相当的好。

另外,我们注意到,它计时所用的方法是 SystemClock.elapsedRealtime(),而不是System.currentTimeMillis()。 这两个方法有啥区别呢?区别在于currentTimeMillis用户可以更改,即当修改用户时间这个值会变,而前者则是开机后的绝对流逝时间,是无法手动去修改这个值的。因此,使用SystemClock.elapsedRealtime()会非常确准的计算时间差。

volley还有一个特点是,我们注意下这些Set方法。
技术分享
大多数时候,他们都有一个返回值,return this. 这种写法能够很方便的把各个赋值语句串起来(像builder模式),让调用者非常舒服的使用代码。

总之,这个Request类在写法上考虑了很多的细节,同时又有一些技巧,这些都值得我们学习。

volley 框架剖析(三) Request类精解

标签:volley

原文地址:http://blog.csdn.net/zoudifei/article/details/45288725

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!