Volley框架的基本解读(一)

君子曰:学不可以已。青,取之于蓝,而青于蓝;冰,水为之,而寒于水。


总是幻想能在技术的道路上更进一步,可大多数时候总是提不起动力,最近公司闲来无事,便开始浏览各种博客,受益良多,便突发奇想写一栏自己的博客,说来惭愧,虽从业时间不短,但在android领域依然是一位技术小白,机缘巧合下看到一位大神写的网络框架解析,受到启发,于是苦心钻研了volley框架的源码,略有所得,分享给大家。


另外,这篇文章适合于像我这样的技术小白,如果你是大神,请无视。


volley框架是2013年Google I/O大会上发布的一款android平台轻量级网络通信库,能使网络通信更快,更简单,更健壮,特别适合数据量不大但是通信频繁的场景,下面进入正题,首先我们先看看volley的使用:


RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);
		StringRequest stringRequest = new StringRequest("http://www.baidu.com", new Response.Listener<String>() {
			@Override
			public void onResponse(String response) {
				Log.d("TAG", response);
			}
		}, new Response.ErrorListener() {
			@Override
			public void onErrorResponse(VolleyError error) {
				Log.e("TAG", error.getMessage(), error);
			}
		});
		mQueue.add(stringRequest);


上面是一个volley的get请求,volley的使用非常简单,从Volley这个静态方法的工具类中获取RequestQueue,这是一个队列用来调度所有的Request,StringRequest是Request的一个具体实现子类,三个参数分别是请求的URL,请求成功的回调,请求失败的回调,最后将request加入RequestQueue就完成了网络请求。


我们从源头入手,先看看Volley这个工具类是如何实现的,下面是源码:


public static RequestQueue newRequestQueue(Context context) {
        return newRequestQueue(context, null);
}


我们可以看到该方法是调用了另一个同名的重载方法,好,让我们继续往下看:


public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
    // 定义缓存路径
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        // 根据版本使用HttpStack,实际上就是对HttpClient或HttpURLConnection的封装
        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }
        
        // 网络接口的基本实现,处理网络请求或失败重试
        Network network = new BasicNetwork(stack);

        // 请求队列,处理缓存与网络交互
        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

        return queue;
}

这里就是newRequestQueue方法的具体实现了,让我们一句一句慢慢分析,首先创建的File文件是一个缓存路径,用来保存需要缓存的请求成功后的返回数据,userAgent 是一个请求代理的标识,用于AndroidHttpClient的创建,stack 是我们传进来的参数,默认为null,可以看到源码根据当前api决定使用哪一种网络请求,api低于9使用HttpClientStack,高于9则使用HurlStack,而这两个类正是HttpClient与HttpURLConnection的封装,如果这两个类大家都不想使用,自己在外部创建传入也是可以的,因为这个方法也是一个静态公开的方法,之后就是创建网络处理类与缓存处理类,再传入RequestQueue中,启动这个队列让其工作,然后将RequestQueue返回。


到这里大家可能会有很多疑惑,比如HurlStack,HttpClientStack,BasicNetwork,DiskBasedCache都是什么鬼等等,别急,这篇博客会一一说道,下面我们再来看看RequestQueue源码:

public RequestQueue(Cache cache, Network network) {
        this(cache, network, DEFAULT_NETWORK_THREAD_POOL_SIZE);
}


大家还记得吧,我们创建RequestQueue时就传入了这两个参数,它是调用了另一个构造方法,DEFAULT_NETWORK_THREAD_POOL_SIZE的默认值是4,用于决定开启多少条网络调度线程,再往下看:

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


ExecutorDelivery类是Volley框架中的结果分发类,传入Handler以为了能够让需要的方法跑在主线程,我们也先放一放,接着看:

public RequestQueue(Cache cache, Network network, int threadPoolSize,
            ResponseDelivery delivery) {
        mCache = cache;
        mNetwork = network;
        mDispatchers = new NetworkDispatcher[threadPoolSize];
        mDelivery = delivery;
}


RequestQueue的构造方法,最终到这里来,将缓存处理类,网络处理类,网络调度类,结果分发类用成员变量给予保存,threadPoolSize的值就是之前我们说的4,在上面我们分析了Volley类的源码,RequestQueue被创建后,随即调用了start方法,接着我们看看start做了什么:


public void start() {
        stop();  // Make sure any currently running dispatchers are stopped.
        // Create the cache dispatcher and start it.
        mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
        mCacheDispatcher.start();

        // Create network dispatchers (and corresponding threads) up to the pool size.
        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
                    mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }
}


是不是一目了然,简单的分为三块,stop方法,用于终止正在运行的线程:

public void stop() {
        if (mCacheDispatcher != null) {
            mCacheDispatcher.quit();
        }
        for (int i = 0; i < mDispatchers.length; i++) {
            if (mDispatchers[i] != null) {
                mDispatchers[i].quit();
            }
        }
}


quit方法我们暂时不说,大家理解为一个暂停线程的方法即可,mCacheDispatcher 与networkDispatcher分别是缓存调度与网络调度,我们可以明确的看出,这里开启了一条缓存调度与4条网络调度,如果有人疑惑为什么是4条?那你请回看RequestQueue的构造方法的源码。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值