Volley框架源码
来源:互联网 发布:淘宝我的空间3d形象 编辑:程序博客网 时间:2024/05/21 09:50
本文主要大概介绍Volley框架源码的骨干东西,内部队列调度,业务流程不详细说。
使用Volley的过程很简单
1、newRequestQueue获取请队列;
2、mQueue.add(stringRequest);将请求加入队列
RequestQueue mQueue = Volley.newRequestQueue(context);StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.i(TAG, "response:" + response); iRequest.onResult(response); }}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, "error:" + error); ExVolleyException exception = new ExVolleyException(); if(error.networkResponse != null){ iRequest.onError(exception.getStatusError(error.networkResponse.statusCode)); }else { iRequest.onError(exception.getStatusError(500)); } }}) { @Override public Map<String, String> getHeaders() throws AuthFailureError { return getRequestHeaders(TYPE_HEADER.TYPE_NORMAL); } @Override protected Map<String, String> getParams() throws AuthFailureError { return super.getParams(); }};mQueue.add(stringRequest);
=======================================================
先从newRequestQueue进入源码分析
一、Volley.class—–>newRequestQueue(Context,HttpStack)
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) { } 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;}
(1) 主要是根据版本是否大于9(android2.3),初始化HttpStack,主要的区别是:用于网络请求的方式,根据不同的HttpStack初始化,后面用于请求网络的方式不一样,大于9的初始化的HttpStack后面的请求用的HttpUrlConnection而小于9的初始化,后面请求网络用的是httpClient。
(2)初始化BasicNetwork(实现了Network)实际的请求网络的类
(3)初始化一个队列,并将初始化好的缓存和网络请求实例入参
(4)queue.start();
/** * Starts the dispatchers in this queue. */public void start() { stop(); // Make sure any currently running dispatchers are stopped./** @param cacheQueue Queue of incoming requests for triage* @param networkQueue Queue to post requests that require network to* @param cache Cache interface to use for resolution* @param delivery Delivery interface to use for posting responses*/ // 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(); }}
主要是缓存调度器和网络请求调度器的初始化及start;
两个调度器均继承线程,在RequestQueue构造时,默认缓存调度器线程有4个;
二、mQueue.add(stringRequest); RequestQueue—->add(Request)方法分析
/** * Adds a Request to the dispatch queue. * @param request The request to service * @return The passed-in request */ public <T> Request<T> add(Request<T> request) { // Tag the request as belonging to this queue and add it to the set of current requests. request.setRequestQueue(this); synchronized (mCurrentRequests) { mCurrentRequests.add(request); } // Process requests in the order they are added. request.setSequence(getSequenceNumber()); request.addMarker("add-to-queue"); // If the request is uncacheable, skip the cache queue and go straight to the network. if (!request.shouldCache()) { mNetworkQueue.add(request); return request; } // Insert request into stage if there's already a request with the same cache key in flight. synchronized (mWaitingRequests) { String cacheKey = request.getCacheKey(); if (mWaitingRequests.containsKey(cacheKey)) { // There is already a request in flight. Queue up. Queue<Request<?>> stagedRequests = mWaitingRequests.get(cacheKey); if (stagedRequests == null) { stagedRequests = new LinkedList<Request<?>>(); } stagedRequests.add(request); mWaitingRequests.put(cacheKey, stagedRequests); if (VolleyLog.DEBUG) { VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey); } } else { // Insert 'null' queue for this cacheKey, indicating there is now a request in // flight. mWaitingRequests.put(cacheKey, null); mCacheQueue.add(request); } return request; } }
流程大概就是:
1、 request.setRequestQueue(this);请求帮顶请求队列
2、 mCurrentRequests.add(request);同步加入当前请求队列
3、 request.setSequence(getSequenceNumber());
request.addMarker(“add-to-queue”);
请求加标记
4、判断是否缓存,不缓存就直接放到请求队列: mNetworkQueue.add(request);
5、 判断请求等待队列是否包含当前请求:if(mWaitingRequests.containsKey(cacheKey))及是否有相 同请求正在被处理
如果包含,加入到相同请求的等待队列中,
不包含则创建新的当前请求的空队列,添加当前请求到缓存请求队列中
三、最后
在初始化请求队列的时候重新开启了5个线程,4个缓存调度线程组成的缓存调度器,一个请求调度线程,然后具体的缓存、请求逻辑,请求的实现就交给了调度器,这也是volley框架的核心部分,是很细节的地方,主要关注两类调度器里面run方法。
- 源码解析Volley框架
- Volley框架源码分析
- Volley框架源码解析
- Volley框架源码
- volley框架源码解析
- Volley框架(五):Volley源码分析
- Volley框架核心源码分析
- Google Volley框架源码走读
- Google Volley框架源码走读
- Google Volley框架源码走读
- 关于volley框架源码解析
- android-----Volley框架源码分析
- android-----Volley框架源码分析
- 【Android框架】volley源码分析
- Android Volley框架源码解析
- Volley(四) Volley框架(从源码角度分析)
- 网络通讯框架-Volley源码分析(1)
- 网络通讯框架-Volley源码分析(2)
- 获取时间戳,转化时间字符串
- Eclipse Web 开发的使用
- Vue1.0过滤器
- hdu 1166 敌兵布阵(cdq分治)
- mac下如何安装python3.x
- Volley框架源码
- windows上解决git每次重复输入账号密码
- 个人笔记—C++删除指定路径文件实现
- Struts2常见的常量配置
- 使用SpringMVC进行数据的传送,数据来自mysql数据库 (1)没有使用hibernate
- 欢迎使用CSDN-markdown编辑器
- SQLServer性能调试开关
- 自定义springUtils用来getBean
- 在Windows上配置MongoDB