Volley分析(1)
来源:互联网 发布:淘宝急需开通直播 编辑:程序博客网 时间:2024/06/08 18:41
接下来我会写一个分析volley源码的系列。
这只是完整的请求过程,但是不是最优的。
实际上调用的方法是:
HttpStack、HurlStack、HttpClientStack;BasicNetwork、HttpStack;这两类之间的关系是继承关系;HttpStack的performRequest方法,与Network的performRequest方法之间的关系,实际上就是包裹关系;NetworkResponse就是对HttpResponse的包裹
上面介绍了简单访问网络的例子;在下一篇博客中会详细介绍volley的使用。
分析的思路:
1.volley简答访问网络
2.volley完整访问网络流程
3.volley工作的原理
4.volley高效的原因
5.怎样高效的使用volley
6.改造volley
首先,我们不考虑volley,如果是我们自己写一个请求网络的工具;首先会将我们自请求封装一下,然后在扔给线程池请求网络,线程池处理完之后返回结果,我们就处理结果。
其实我看过很多网络请求的框架,几乎都是这样处理的,只不过是中间加了很多优化的方法。volley也是这样处理的。
然后再看一段volley请求网络的简单代码:
RequestQueue mRequestQueue = Volley.newRequestQueue(context);JsonObjectRequest req = new JsonObjectRequest(URL, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { VolleyLog.v("Response:%n %s", response.toString(4)); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { VolleyLog.e("Error: ", error.getMessage()); } });mRequestQueue.add(req);
这只是完整的请求过程,但是不是最优的。
首先分析第一句代码:
RequestQueue mRequestQueue = Volley.newRequestQueue(context);
实际上调用的方法是:
public static RequestQueue newRequestQueue(Context context, HttpStack stack) { //将缓存放在应用的Cache/volley目录下面 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) { //stack就是请求网络的工具,里面只有一个请求网络的方法 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); //启动请求队列,所以获取一个RequestQueue队列之后,不用在start了。直接add请求就行了 queue.start(); return queue; }
HttpStack、HurlStack、HttpClientStack;BasicNetwork、HttpStack;这两类之间的关系是继承关系;HttpStack的performRequest方法,与Network的performRequest方法之间的关系,实际上就是包裹关系;NetworkResponse就是对HttpResponse的包裹
第二句代码是创建了一个JsonRequest。
第三句代码是将request加入了请求队列中。
上面就是请求网络的一个简单的过程,但是不能用于实战。
下面会阐述理由的
上面mQueue.add(request)这句代码有风险。
在看一下add这个方法,之前先说明下面这4个集合的功能,因为一切操作都是围绕这4个集合来的。
private final Map<String, Queue<Request<?>>> mWaitingRequests = new HashMap<String, Queue<Request<?>>>(); /** * The set of all requests currently being processed by this RequestQueue. A Request * will be in this set if it is waiting in any queue or currently being processed by * any dispatcher. */ private final Set<Request<?>> mCurrentRequests = new HashSet<Request<?>>(); /** The cache triage queue. */ private final PriorityBlockingQueue<Request<?>> mCacheQueue = new PriorityBlockingQueue<Request<?>>(); /** The queue of requests that are actually going out to the network. */ private final PriorityBlockingQueue<Request<?>> mNetworkQueue = new PriorityBlockingQueue<Request<?>>();
mNetworkQueue:是用来装真正用来请求网络的request的,mDispatchers就是用来请求网络的线程
mCacheQueue:是装载需要缓存的request的,mCacherDispathers就是负责从缓存中取数据的线程
mWaitingRequests:是装载重复的request
mCurrentRequests:是装载正在被处理的request
下面的add方法是,添加请求的唯一入口;4大集合在里面的功效,上面的表格表示的已经很清楚了。
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; } }
上面介绍了简单访问网络的例子;在下一篇博客中会详细介绍volley的使用。
0 0
- Volley分析(1)
- Android Volley源码分析(1)
- Volley分析
- Volley 分析
- 网络通讯框架-Volley源码分析(1)
- volley源码的简单分析(1)
- Android Volley分析
- Android-Volley源码分析
- Volley框架分析
- [Android]volley源码分析
- Volley源码分析
- Volley源码分析
- Volley框架分析
- Volley框架深入分析
- Volley源码分析
- Volley -- 源码分析
- Android-Volley源码分析
- Volley源码流程分析
- java 字符串中去除特定的字符
- poj 1185
- 【产品经理】沟通篇之如何与前端沟通
- jQuery属性,验证码失效,动态内容加载
- Cocos2dx 3.2 横版过关游戏Brave学习笔记(七)
- Volley分析(1)
- 最短路径算法(java实现)
- 华为机试题
- VS2013解决html文件无法打开设计视图
- android lint 安全分析
- arm-6410友善之臂 uboot linux内核.文件系统移植
- c++二叉树的非递归建立和遍历
- java 配置及Eclipse安装
- VMware Workstation 虚拟磁盘(VMDK) 编程【抛砖引玉】