Android组件Volley学习
来源:互联网 发布:数据挖掘产品 编辑:程序博客网 时间:2024/06/07 20:00
1. 项目地址本地下载
2. 参考博文
http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/
http://blog.csdn.net/guolin_blog/article/details/17482095
Volley是Google提供的网络通信库,通过它可以使得从网络获取数据更加的方便。它对网络的请求做了很多封装优化,让开发者更加便捷的开发。在新的Android文档中,已经加入了Volley方面的部分,在Training部分。网上有很多对它的参考,当然,Android文档就是一份很好的参考。大牛都批评只会使用而不去研究它源码的码农,但,我还是先浅尝辄止,不去学习的它的源码。不过,他们都推荐它的源码写得非常好,那当然要适时的找时间学习它的源码。下面记录下它的使用方法,涉及到的有异步请求文本,json,图片等请求,Volley是对返回的字节流做了封装。当然,我们也可以根据需要继承Request,定制自己的Request。另外,需要记录的是内存级别和硬盘(sd卡)的缓存处理。
我们首先要获得一个RequestQueue对象,文档推荐使用单例模式。推荐的方法是实现一个单模式类,提供一个获取对象的单例方法。如下:
public RequestQueue getRequestQueue() { if (mRequestQueue == null) { // getApplicationContext() is key, it keeps you from leaking the // Activity or BroadcastReceiver if someone passes one in. mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); } return mRequestQueue; }
其中,Volley#newRequestQueue(Context context) 这个静态方法的参数很讲究。不推荐使用Activity的context,而是使用Application的context,正如上面的代码所示。这样,即使一个Activity销毁了,RequestQueue对象也不会跟随它销毁,而是和这个APP的生命周期相关联,避免了重复的生成。
接着,我们来看请求文本数据,如下:
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() { @Override public void onResponse(String response) { // Display the first 500 characters of the response string. mTextView.setText("Response is: "+ response.substring(0,500)); }}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mTextView.setText("That didn't work!"); }});
StringRequest有多个重载的构造方法,可以使用GET方式和POST方式,相应的有请求成功和请求失败的回调监听函数。那么对于POST方式,如何传递参数呢?在JsonObjectRequest的构造方法中,有个参数选项可以传进一个Map结构的键值对参数。而StringRequest 中确没有,参考博文的方法是,重写StringRequest的getParams()方法,如下:
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) {@Overrideprotected Map<String, String> getParams() throws AuthFailureError {Map<String, String> map = new HashMap<String, String>();map.put("params1", "value1");map.put("params2", "value2");return map;}};
有了请求对象后,就把该对象加入的请求队列RequestQueue中即可。
// Add the request to the RequestQueue.queue.add(stringRequest);
如何请求JSON数据呢?就是构造一个JsonObjectRequest或者JsonArrayRequest请求对象,形式和上面大同小异。然后加入到请求队列中即可。
那如何,请求图片资源呢?记录这两种好用的方式。一种是构造一个ImageRequest对象,然后在请求成功的回调函数中ImageView#setImageBitmap 即可。构造方法中可以指定图片的大小。
ImageRequest imageRequest = new ImageRequest(imgUrl1, new Listener<Bitmap>() {@Overridepublic void onResponse(Bitmap response) {mImageView1.setImageBitmap(response);}}, 200, 200, Config.ARGB_8888, new ErrorListener() {@Overridepublic void onErrorResponse(VolleyError error) {Log.e(TAG, "imageRequest-->"+error.getMessage());}});mQueue.add(imageRequest);
和上面的类似。另一种功能强大一些,它可以设定加载中的图片,加载失败的图片,和内存缓存的策略。该方法使用的是ImageLoader类实现,首先生成一个该对象:
mImageLoader = new ImageLoader(mQueue, new LruBitmapCache(this));
第一个参数是请求队列,第二个参数是缓存策略。文档中提供一个例子。当然,我们可以自己实现或者实现为不使用缓存。最后,我们调用一下#get方法就可以了,
mImageLoader.get(imgUrl2, ImageLoader.getImageListener(mImageView2, android.R.drawable.alert_dark_frame, android.R.drawable.edit_text));
内存缓存中,有个奇怪的事,我在文档提供的 LruBitmapCache类的 #getBitmap 方法中,加入log观察,发现多次请求同一个url图片时,它的 #get 方法返回的对象返回为null,根本就没有缓存到内存中。
基本的网络请求,就如上。有时,我们需要设置一下HTTP头,该如何做?覆盖请求对象的 #getHeaders 方法即可,
@Override public Map<String, String> getHeaders() throws AuthFailureError { HashMap<String, String> headers = new HashMap<String, String>(); headers.put("CUSTOM_HEADER", "Yahoo"); headers.put("ANOTHER_CUSTOM_HEADER", "Google"); return headers; }
有时,当我们退出Activity时,希望取消正在进行的网络操作,我们可以调用RequestQueue的一系列的 #cancel* 方法,比如,
public static final String TAG = "MyTag";StringRequest stringRequest; // Assume this exists.RequestQueue mRequestQueue; // Assume this exists.// Set the tag on the request.stringRequest.setTag(TAG);// Add the request to the RequestQueue.mRequestQueue.add(stringRequest);
@Overrideprotected void onStop () { super.onStop(); if (mRequestQueue != null) { mRequestQueue.cancelAll(TAG); }}
有时,我们需要根据自己的需求封装请求返回的格式,那么我们可以继承Request来实现一个,文档中给出一个Gson的例子,是很好的参考,
public class GsonRequest<T> extends Request<T> { private final Gson gson = new Gson(); private final Class<T> clazz; private final Map<String, String> headers; private final Listener<T> listener; /** * Make a GET request and return a parsed object from JSON. * * @param url URL of the request to make * @param clazz Relevant class object, for Gson's reflection * @param headers Map of request headers */ public GsonRequest(String url, Class<T> clazz, Map<String, String> headers, Listener<T> listener, ErrorListener errorListener) { super(Method.GET, url, errorListener); this.clazz = clazz; this.headers = headers; this.listener = listener; } @Override public Map<String, String> getHeaders() throws AuthFailureError { return headers != null ? headers : super.getHeaders(); } @Override protected void deliverResponse(T response) { listener.onResponse(response); } @Override protected Response<T> 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)); } }}
现在,还有一个较重要的问题要记录,就是缓存问题。Volley默认是对每一个url 都缓存到sd卡中(实验得出)。默认大小是5M。那么我们如何取消缓存或者修改缓存大小呢?修改缓存大小,可以如下(参考文档),
RequestQueue mRequestQueue;// Instantiate the cacheCache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap// Set up the network to use HttpURLConnection as the HTTP client.Network network = new BasicNetwork(new HurlStack());// Instantiate the RequestQueue with the cache and network.mRequestQueue = new RequestQueue(cache, network);// Start the queuemRequestQueue.start();String url ="http://www.myurl.com";// Formulate the request and handle the response.StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { // Do something with the response }}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { // Handle error }});// Add the request to the RequestQueue.mRequestQueue.add(stringRequest);...
那么,如何设置不进行缓存呢,暂时没有发现直接的方法,但阅读源码,可以很快的实现,方法如下,
/** * 没有硬盘缓存 * @param context * @param stack * @return */ public static RequestQueue newRequestQueue(Context context, HttpStack stack) { 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 NoCache(), network); queue.start(); return queue; }
和原来代码中不同的是,删除了一些缓存初始化的代码,以及构造RequestQueue请求队列时,传入的是 NoCache对象,这样即可。我们也可以通过RequestQueue#getCache方法获得Cache对象,然后进行移除指定key的缓存文件,或者clear 清空全部。这样,功能就达到了组件Android-Universal-Image-Loader所能实现的。
- Android组件Volley学习
- Android Volley组件的优化
- Android Volley组件的优化
- Android Volley学习
- Android--Volley---RequestQueue学习
- android Volley 学习摘记
- Volley学习(一)Android Volley源码解析
- Android 第三方组件Volley加载网络
- Android Volley 学习笔记 1
- android框架Volley学习demo
- Android Volley框架学习笔记
- android Volley框架学习一
- Android——Volley学习
- android框架学习之Volley
- Android-volley框架学习笔记
- 【Android开发】Volley学习笔记
- android网络框架volley学习之Volley类
- Android开发-高级网络组件(1)使用Volley登陆-AndroidStudio
- Google I/O 2015 倒计时
- HDU 4004 The Frog's Games
- String类的equals和==
- 用Xcode6进行ios开发中,修改模拟器键盘显示中文
- H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
- Android组件Volley学习
- Servlet自学第26讲:禁用cookie后还能继续使用session的方法
- mysql增加用户
- QT 下载文件
- eclipse搜索的正则表达式
- Android开发面试经——1.常见人事面试问题
- C/C++编译器错误代码大全
- JAVA 读写 Excel--jexcel
- 网上有什么办法彻底删除手机通话记录和短信