volley系列以郭大神的博客为学习材料。贴链接:http://blog.csdn.net/guolin_blog/article/details/17482095
额,还有这个大神的:http://blog.csdn.net/t12x3456/article/details/9221611
一、多会用Volley
Android系统主要提供了HttpURLConnection和HttpClient两种方式来进行Http通信。不过这俩有些复杂,若不进行适当封装的话,会写出不少重复代码。于是,一些Android网络通信框架应用而生,比如AsynHttpClient,他把Http所有通信细节全部封装在了内部,只需简单调用几步代码就可完成通信操作。再比如Universal-Image-Loader,他使得在界面上显示网络图片的操作变得极度简单,开发者不用关心如何从网络上获取图片,也不用关心开启线程、回收图片资源等细节。
Volley可以说是把AsyncHttpClient和Universal-Image-Loader的优点集于一身。除了简单易用外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如下载文件等,Volley的表现就会很糟糕。
屏幕旋转时,有时会导致再次从网络得到数据。为避免这种不必要的网络访问,我们可能需要自己写很多针对各种情况的处理。再比如ListView,滚动过快,可能导致有些网络请求返回的时候,早已经滚过了当时的位置,根本没必要显示在list里了,这些没必要的数据还是会浪费系统的各种资源。
二、下载Volley
贴大神的地址:http://download.csdn.net/detail/sinyu890807/7152015
Volley提供的功能:
1)JSON、图像等的异步下载2)网络请求的排序3)网络请求的优先级处理4)缓存5)多级别取消请求6)和Activity生命周期的联动(Activity结束时同时取消所有网络请求)。
三、用法简单,基本上都类似。
创建一个RequestQueue对象,创建一个request对象,然后将request对象添加到RequestQueue对象中。
RequestQueue是一个请求队列对象,它可以缓存所有的HTTP请求,然后按照一定的算法并发的发出这些请求。RequestQueue内部设计就是非常适合高并发的,因此一般都定义一个全局可用的RequestQueue对象就足够了。
1、StringRequest的用法
RequestQueue mQueue=Volley.newRequestQueue(this); StringRequest stringRequest=new StringRequest("http://www.baidu.com", new Response.Listener<String>() { @Override public void onResponse(String response) { Toast.makeText(getApplicationContext(), response, 1).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(getApplicationContext(), "出错了", 1).show(); } }); mQueue.add(stringRequest);
StringRequest需要三个参数:url地址,服务器响应成功的回调,服务器响应失败的回调。
怎么发出一个POST请求呢?
StringRequest stringRequest=new StringRequest(Method.POST, url, listener, errorListener);
提交给服务器的参数又该怎么设置呢?StringRequest中并没有提供设置POST参数的方法,但是当发出POST请求的时候,Volley会尝试调用StringRequest的父类----Request中的getParams()方法来获取POST参数,那么解决方法自然就有了,只需在StringRequest的匿名类中重写getParams()方法,在这里设置POST参数就可以了,代码如下:
StringRequest stringRequest = new StringRequest(Method.POST, url, listener, errorListener) { @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> map = new HashMap<String, String>(); map.put("params1", "value1"); map.put("params2", "value2"); return map; } };
是不是有点麻烦?连设置POST参数的方法都没有。但不要忘记,Volley是开源的,只要你愿意,你可以自由地在里面添加和修改任何的方法,轻松就能定制出一个属于自己的Volley版本。
2、JsonRequest用法
类似于StringRequest,JsonRequest也是继承自Request类的。不过由于JsonRequest是一个抽象类,因此由于JsonRequest是一个抽象类,因此无法直接创建它的实例,那么只能从它的子类入手了。JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayRequest。
RequestQueue mQueue=Volley.newRequestQueue(this); JsonObjectRequest jsonObjectRequest=new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", null, new Response.Listener<JSONObject>() { <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span> public void onResponse(JSONObject response) { <span style="white-space:pre"> </span> str=response.toString(); <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span>}, new Response.ErrorListener() { <span style="white-space:pre"> </span> @Override <span style="white-space:pre"> </span> public void onErrorResponse(VolleyError error) { } <span style="white-space:pre"> </span>}); mQueue.add(jsonObjectRequest);
3、使用Volley加载网络图片
1)ImageRequest的用法。ImageRequest也是继承Request的,所以它的用法也基本相同。
代码:
第一个参数为URL地址,第二个是图片请求成功的回调,第三个和第四个分别用于指定允许图片最大的宽度和高度,如果指定的网络图片的高度或宽度大于这里的最大值,则会对图片进行压缩;指定成0的话就表示不管图片多大,都不会进行压缩。第五个参数指定图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据四个字节大小,而RGB_565则表示每个图片像素占据2个字节大小。第六个参数是图片请求失败的回调,可在请求失败时显示一张默认图片。
2)ImageLoader的用法
介绍:也可用来加载网络上的图片,并且它的内部也是使用ImageRequest来实现的,不过ImageLoader明显要比ImageRequest更加高效,因为它不仅可以帮我们对图片进行缓存,还可以过滤掉重复的链接,避免重复发送请求。
用法:①创建一个RequestQueue对象②创建一个ImageLoader对象③获取一个ImageListener对象④调用ImageLoader的get()加载网络上的图片。
3)NetworkImageView用法
这是一个自定义控件,继承自ImageView,具备ImageView的所有功能,并且在原生的基础上加入了加载网络图片的功能。用法比前两种更简单。
①创建一个RequestQueue对象②创建一个ImageLoader对象③在布局文件中添加一个NetworkImageView控件④在代码中获取该控件,设置要加载的图片地址。
NetworkImageView如何压缩图片:它是一个控件,加载图片时它会自动获取自身的宽高,然后对比网络图片的宽高,再决定是否需要对图片进行压缩。自动完成压缩。如果不想压缩,只需将宽高设为wrap_content即可。
四、定制自己的Request
五、取消网络请求
没有Volley时,如果在一个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()); ... }