Volley主页 https://android.googlesource.com/platform/frameworks/volley
http://www.youtube.com/watch?v=yhv8l9F44qo&feature=player_embedded
1. ?么是Volley
在这之前,我?程序?要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,今年的Google I/O 2013上,Volley发布了?Volley是Android平台上的网络通信库,能使网络通信更快,更?单,更健???
这是Volley名称的由来: a burst or emission of many things or a large amount at once
在Google IO的演讲上,其配图?幅发射火弓?的图,有点类似流星??下图
其实,从这幅图,我们也可以看出来,Volley特别适合数据量不大但??信频繁的场???
1.1. Volley引入的背?
在以前,我们??如下很?麻烦的问题??
比?以前从网上下载图片的步???样的流程?
- 在ListAdapter#getView()里开始图像的读取?
- 通过AsyncTask等机制使用HttpURLConnection从服务器去的图片资源
- 在AsyncTask#onPostExecute()里??应ImageView的属性??
而在Volley下,?要一?数即?详细见后面的例子?
再比如,屏幕旋转的时候,有时候会导致再?从网络取得数??为了避免这种不必?的网络??我们??要自己写很?针?各?情况的?理,比?cache?么的?
再有,比如ListView的时候,我们滚动过快,可能?致有些网络?求返回的时?,早已经滚过了当时的位?根本没必要显示在list里了,虽然我?以?过ViewHolder来保持url等来实现防?两?取得,但?些已经没有必须?的数?还是会浪费系统的各?资源?
1.2. Volley提供的功?
?单来说,它提供了如下的便利功能:
- JSON,图像等的异步下载;
- 网络请求的排序(scheduling?
- 网络请求的优先级处理
- 缓存
- 多级?消??
- 和Activity和生命周期的联动(Activity结束时同时取消所有网络?求)
2. 使用前的准?
引入Volley非常?单,首先,从git库先克隆??来:
引用
git clone https://android.googlesource.com/platform/frameworks/volley
然后编译为jar包,再在?的工程里import进来?
注意,这?要求?低SDK版本为Froyo,即至少要?置android:minSdkVersion?以上?
3.使用例子
下面?单看看?何使用Volley
3.1. ??单的get请求
这个例子很简单,从网络取得JSON对象,然后打印出来??
mQueue = Volley.newRequestQueue(getApplicationContext());mQueue.add(new JsonObjectRequest(Method.GET, url, null, new Listener() { @Override public void onResponse(JSONObject response) { Log.d(TAG, "response : " + response.toString()); } }, null));mQueue.start();
3.2. 给ImageView设置图片?
// imageView?个ImageView实例 // ImageLoader.getImageListener的?二个参数?认的图片resource id // ??数是请求失败时?的资源id,可以指定为0 ImageListener listener = ImageLoader.getImageListener(imageView, android.R.drawable.ic_menu_rotate, android.R.drawable.ic_delete); mImageLoader.get(url, listener);
ImageLoader的方法都?要从主线程里来调用??
3.3. 使用NetworkImageView
Volley提供了一?的控件NetworkImageView来代替传统的ImageView,这?件的图片属?可以?过
mImageView.setImageUrl(url, imageLoader)
来?定??且,这?件在?父控件detach的时候,会自动取消网络?求的,即完全不用我们担心相关网络请求的生命周期问题??
示例代码如下?
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache()); ... ... if(holder.imageRequest != null) { holder.imageRequest.cancel(); } holder.imageRequest = mImageLoader.get(BASE_UR + item.image_url, holder.imageView, R.drawable.loading, R.drawable.error);
注意,这里使用的不是ImageView控件,?是Volley新提供的com.android.volley.NetworkImageView?
另?,注意这里:
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
ImageLoader构?函数的??数是?个ImageCache的实例(严格来?,是实现ImageCache接口的某具体类的实例?
ImageCache的定义?下(在ImageLoader.java里)?
/** * Simple cache adapter interface. If provided to the ImageLoader, it * will be used as an L1 cache before dispatch to Volley. Implementations * must not block. Implementation with an LruCache is recommended. */ public interface ImageCache { public Bitmap getBitmap(String url); public void putBitmap(String url, Bitmap bitmap); }
下面的网??个lru的cache实现例子,?参?:
https://github.com/suwa-yuki/VolleySample/blob/master/src/jp/classmethod/android/sample/volley/BitmapCache.java
3.5. 使用?定制的request
我们也可以?过继承Request根据?的需求来定制?的request
@Override protected Response parseNetworkResponse(NetworkResponse response) { try { String json = new String( response.data, HttpHeaderParser.parseCharset(response.headers)); return Response.success( gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JsonSyntaxException e) { return Response.error(new ParseError(e)); } }
这?代码节?自?https://gist.github.com/ficusk/5474673
里面使用的gson(com.google.gson.Gson)是JSON的序列化和反序列化的库,?在JSON和java model object之间进???
以下?用自定制request的例子:
mRequestQueue.add( new GsonRequest(url, ListResponse.class, null, new Listener() { public void onResponse(ListResponse response) { appendItemsToList(response.item); notifyDataSetChanged(); } } }
4. Volley的架构??
Volley使用了线程池来作为基?结构,主要分为主线程,cache线程和network线程?
主线程和cache线程都只有一?而NetworkDispatcher线程?有??这样能解决比并???。?下图:
如果在一个Activity里面?了网络?求,而在这个网络请求还没返回结果的时候,如果Activity?束了,则我们?要写如下代码作为防守?
@Override public void onPostExecute(Result r) { if (getActivity() == null) { return; } // ... }
Activity??后,如果继续使用其中的Context等,除了无辜的浪费CPU,电池,网络等资源,有可能还会?致程序crash,所以,我们?要?理这种一场情况??
使用Volley的话,我?以在Activity停?的时候,同时取消?有或部分?成的网络请求?
Volley里所有的请求结果会返回给主进程,如果在主进程里取消了某些请求,则这些请求将不会?返回给主线程?
比?,可以针对某些个request做取消操作:
@Override public void onStop() { for (Request <?> req : mInFlightRequests) { req.cancel(); } ... }
或?,取消这个队列里的?有?求:
@Override pubic void onStop() { mRequestQueue.cancelAll(this); ... }
也可以根据RequestFilter或?Tag来终止某些?求:
@Override public void onStop() { mRequestQueue.cancelAll( new RequestFilter() {}) ... // or mRequestQueue.cancelAll(new Object()); ...
5.总结
从演讲的例子来看,Volley应??化了网络通信的一些开发,特别?对?下两种情况:
- JSON对象
- 图片加载
但是这个东西也有不实用的地方,比如大数据(large payloads ),流媒体,这些case,还?要使用原始的方法,比如Download Manager等??
总之,?果你要编写网络程序,??以?虑?始使用Volley?
git上的??
https://github.com/suwa-yuki/VolleySample/tree/master/src/jp/classmethod/android/sample