Volley全解析
来源:互联网 发布:师洋淘宝店骂人 编辑:程序博客网 时间:2024/06/05 03:08
什么是Volley
- Volley 的单词涵义是:迸发、万箭齐发。 是比喻的命名方式,寓指网络请求并发效率高。
Volley 的重要方法
- mQueue = Volley.newRequestQueue(context);
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; }
Volley 在新建RequestQueue 的时候,其实是新建了两个 Queue, 一个CacheQueue(用于获取获取本地缓存结果),一个NetworkQueue(用于网络请求); 在 queue.start(); 中, start 的是 一个 CacheDispatcher 和 4个 NetworkDispatcher, 分别作用在前面的两个Queue
mQueue = Volley.newRequestQueue(context); 最好放在 Application 中,整个app 只有一个requestQueue.
new ExecutorDelivery(new Handler(Looper.getMainLooper())) 在RequestQueue 的参数中,有一个delivey 将handler 传入其中,后面就是通过handler 的post 在主线程中回调 Listener 的。
需要注意一下的是,网络请求,在android 版本2.2 以前建议使用的是 httpclient, 而在 2.2 以后建议使用的是HttpUrlConnection 。 5.2 以后,若使用 HttpClient 会出现通篇的warning, 这是因为google 已经强烈要求使用 HttpUrlConnection 了。 原因是: HttpUrlConnection 相比于 HttpClient 体积更小,API 更为简单,而且扩展性比HttpClient 好很多,在压缩、缓存、省电、减少流量等各方面都要突出一些。 所以HttpUrlConnection 更适用于 android。
- mQueue.add(new Request());
/** * Adds a Request to the dispatch queue. * @param request The request to service * @return The passed-in request */ public Request add(Request 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; } }
Request 是完全可以自定义的。Volley 提供的 Request 有 StringRequest 、 JsonObjectRequest、 JsonArrayRequest、 ImageRequest 等等。
往Queue中添加Request 的过程是: 先判断 Request 的 shouldCache 属性,如果该属性为 true 则将 Request 添加到 CacheQueue 中,当然其中会有 waitingRequest 的 list 来控制相同的 请求不再重复添加。 如果该属性为 false, 则直接加入到 NetworkRequest 中。如果本地没有缓存,即在CacheQueue处理过后,发现没有数据,则重新添加到NetworkQueue 中。 在请求数据回来之后,再次判断 showCache 来写缓存及返回数据到UI线程。
自定义Request
- 覆盖 ContentType 属性
@Override public String getBodyContentType() {// super.getBodyContentType(); return "application/json"; }
- 覆盖 getBody() , Volley 默认的添加 content params 的方法是添加 “&”等等,与我们经常使用的是不一样的,所以覆盖 getParams() 还达不到我们想要的效果,所以直接覆盖 getBody() 方法。
if (mParams != null && !mParams.isEmpty()) { String ss = JSON.toJSONString(mParams); return ss.getBytes(); } return super.getBody();
- 添加自定义 header
@Override public Map<String, String> getHeaders() throws AuthFailureError { return mHeaderParams; }
- 结果处理
@Override protected Response<T> parseNetworkResponse(NetworkResponse response) { // 在这处理 }
- 其他
默认的 get 请求, 传入的 params 不会被处理,所以需要在外面将 url 自行拼接好再传入 Volley 中。
private String toGetUrl(String url, Map<String, Object> entity) { StringBuilder urlSB = new StringBuilder(); if (entity != null && !entity.isEmpty()) { for (String key : entity.keySet()) { if (urlSB.length() != 0) { urlSB.append("&"); } urlSB.append(key + "=" + Uri.encode(JSON.toJSONString(entity.get(key)))); } } if (urlSB == null || "".equals(urlSB.toString())) { return url; } return url + "?" + urlSB.toString(); }
- 常用属性设置
setShouldCache(false); setRetryPolicy( // 超时时间、retry次数、超时时间乘数 例如第一次5秒 第二次超时想要设置10秒, 乘数就为2 默认为1 可以是float new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT) ); setTag("tag"); // 标记 可用于cancle request
ImageLoader、 NetworkImageView
mNetworkImageView.setDefaultImageResId(R.drawable.ic_launcher); // 默认图片 mNetworkImageView.setErrorImageResId(R.drawable.ic_launcher); // 发生错误时 mNetworkImageView.setImageUrl(URLS[1], MyApplication.genImageLoader());// 请求地址,及 imageloader
- MyApplication
@Override public void onCreate() { super.onCreate(); mInstance = this; mQueue = Volley.newRequestQueue(this); VolleyImageCache lruImageCache = VolleyImageCache.genInstance(); mImageLoader = new ImageLoader(mQueue,lruImageCache); }
- VolleyImageCache
public class VolleyImageCache implements ImageLoader.ImageCache { private static LruCache<String, Bitmap> mMemoryCache; private static VolleyImageCache mVolleyImageCache = new VolleyImageCache(); private VolleyImageCache() { // Get the Max available memory int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getRowBytes() * bitmap.getHeight(); } }; } public static VolleyImageCache genInstance() { return mVolleyImageCache; } @Override public Bitmap getBitmap(String arg0) { return mMemoryCache.get(arg0); } @Override public void putBitmap(String arg0, Bitmap arg1) { if (getBitmap(arg0) == null) { mMemoryCache.put(arg0, arg1); } }}
使用Volley 上传文件
private MultipartEntity mReqEntity = new MutipartEntity(); @Override public String getBodyContentType() { return mReqEntity.getContentType().getValue(); } @Override public byte[] getBody() throws AuthFailureError { if (!CollectionUtils.isCollectionEmpty(mFilePath)) { // upload files ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { mReqEntity.writeTo(bos); } catch (IOException e) { VolleyLog.e("IOException writing to ByteArrayOutputStream"); } return bos.toByteArray(); } return super.getBody(); } private void buildMultipartEntity() { try { for (String filepath : mFilePath) { File file = new File(filepath); FileBody filePart = new FileBody(file); mReqEntity.addPart(file.getName(), filePart); } if (mParams != null && !mParams.isEmpty()) { Iterator<String> keySet = mParams.keySet().iterator(); while (keySet.hasNext()) { String key = keySet.next(); String ss = JSON.toJSONString(mParams.get(key)); mReqEntity.addPart(key, new StringBody(ss)); } } } catch (UnsupportedEncodingException e) { // empty here } }
- Volley全解析
- Volley框架全解析
- Volley用法全解析
- Volley全解析(一):创建一个请求队列
- Android网络编程(三)Volley用法全解析
- Android Volley完全解析(一,二,三,四)全
- Android网络编程(三)Volley用法全解析
- Android网络编程(三)Volley用法全解析
- 【Volley】Volley源码解析
- volley 解析
- Volley解析
- Volley解析
- Volley 解析
- Volley解析
- Volley 解析
- Volley解析
- Volley解析json(三)
- Android Volley完全解析
- Linux下php安装
- IE8下无法打开Internet站点,已终止操作问题解析
- hihoCoder - 1175 - 拓扑排序·二 (拓扑排序的应用)
- C++ 模版类的单向链式线性表
- spring四种依赖注入方式
- Volley全解析
- android 实现代码混淆
- 深入理解HTTP Session
- WebKit的一些笔记3(基础篇)
- tabbarcontroller切换
- Listview 去除顶部阴影
- MathType在word中的使用方法
- Maven实战(八)---模块划分
- 使用JMF在java上使用媒体资源(播放音频等)