Android--Volley基本用法及自定义

 最近在看网络通信这块时,频繁的使用到Http通信,而Android系统中主要提供两种方式来进行Http通信,HttpURLConnection和HttpClient。不过在实际使用在还是有点麻烦和复杂的。经常一不小心就出错,在群里看到有人推荐使用Valley,对齐进行了很好的封装,简单方便。
Volley是2013 GoogleI/O大会上推出的网络通信框架,所以在性能方面是毋庸置疑的。下面算是总结一下自己对于Volley的学习笔记吧。  

下载Volley

如果你的电脑上装有Git,可以使用如下命令下载Volley的源码:

1 git clone https://android.googlesource.com/platform/frameworks/volley

这里放出部分功能看看:

准备工作做好以后就开始正式用了,我这里只以Http通信来介绍,其他的也需要进一步去了解了。

1.StringRequest

1.首先的获取到一个RequestQueue对象  

 

1 RequestQueue mQueue= Volley.newRequestQueue(context);

 

2.发送一条Http请求,我们需要创建一个StringRequest对象:

 1 StringRequest stringRequest=new StringRequest("http://www.baidu.com", new Response.Listener<String>() {
 2             @Override
 3             public void onResponse(String s) {
 4                 Log.d(TAG, "onResponse: "+s);
 5             }
 6         }, new Response.ErrorListener() {
 7             @Override
 8             public void onErrorResponse(VolleyError volleyError) {
 9                 Log.e(TAG,volleyError.getMessage(),volleyError);
10             }
11         });

 这里StringRequest里面需要传入三个参数:第一个参数是目标url地址,第二个是服务器响应成功的的回调,第三个是服务器响应失败的回调。我这里就用log代替具体回调内容。  
3.将这个stringRequest添加到RequestQueue里面:

1 mQueue.add(stringRequest);

打开LogCat就会看到下面这样:StringRequest

至于内容我就先不去管那么多了。能够得到结果就证明没错了。前面用到的只是Get请求,如果你想使用Post则需要添加参数来指定请求类型,如下:

1 StringRequest stringRequest=new StringRequest(Request.Method.POST,"http://www.baidu.com",listener,erroelistener)

这里还只是指定了请求类型如果需要提交给服务器还是不行的,还需要重写getParams()方法,如下:

 简单来说,就是三步操作:  
1.创建一个RequestQueue对象。  
2.创建一个StringRequest对象。  
3.将StringRequest对象添加到RequestQueue里面。  
因为Volley是开源,如果不满足现在的使用,你大可以自己添加或者修改自己想要的方法。同样的JsonRequest和JsonObjectRequest还有ImageRequest用法是相同的,想了解的可以自己实践。

2.ImageLoader

1. 创建一个RequestQueue对象:

1 RequestQueue mQueue= Volley.newRequestQueue(context);

2.创建一个ImageLoader对象:

1 ImageLoader imageLoader=new ImageLoader(mQueue,bitmapCache);

这里第一个参数为一个RequestQueue对象,第二个参数为ImageCache对象。下面会贴出bitmapCache代码

3.调用ImageLoader的get()方法加载图片:

1 imageLoader.get("http://images.cnblogs.com/cnblogs_com/yeshuwei/837768/o_u=733417015,367501698_fm=11_gp=0.jpg",listener);

这里第一个参数为图片的Url地址,第二个参数为一个ImageListener对象,可以通过如下获取:

ImageLoader.ImageListener listener=imageLoader.getImageListener(imageView,R.mipmap.defaulting,R.mipmap.error);

第一个参数用于指定显示图片的ImageView空间,第二个图片为加载时显示的图片,第三个为加载错误时候显示的图片。

你也可以通过在get()方法中指定图片的高度和宽度:

1 imageLoader.get("http://images.cnblogs.com/cnblogs_com/yeshuwei/837768/o_u=733417015,367501698_fm=11_gp=0.jpg",
2 listener, 200, 200);

BitmapCache代码:

 1 public class BitmapCache implements ImageLoader.ImageCache {
 2     private LruCache<String, Bitmap> mCache;
 3 
 4     public BitmapCache() {
 5         int maxSize = 10 * 1024 * 1024;
 6         mCache = new LruCache<String, Bitmap>(maxSize) {
 7             @Override
 8             protected int sizeOf(String key, Bitmap bitmap) {
 9                 return bitmap.getRowBytes() * bitmap.getHeight();
10             }
11         };
12     }
13 
14     @Override
15     public Bitmap getBitmap(String url) {
16         return mCache.get(url);
17     }
18 
19     @Override
20     public void putBitmap(String url, Bitmap bitmap) {
21         mCache.put(url, bitmap);
22     }
23 }

 

ImageLoader就学习到这里了。

3.NetworkImageView

NetworkImageview是一种自定义控件用来加载图片,使用方法如下:

1.创建一个RequestQueue对象

2.在布局文件中加载一个NetworkImageView控件

3.创建一个ImageLoader对象

4.在代码中获取NetworkImageView控件的实例

5.设置要加载的图片

1         bitmapCache=new BitmapCache();
2         networkImageView= (NetworkImageView) findViewById(R.id.network_image_view);
3         RequestQueue mQueue= Volley.newRequestQueue(context);
4         ImageLoader imageLoader=new ImageLoader(mQueue,bitmapCache);
5         networkImageView.setDefaultImageResId(R.mipmap.defaulting);//加载中显示的图片
6         networkImageView.setErrorImageResId(R.mipmap.error);//加载错误时显示的图片
7         networkImageView.setImageUrl("http://images.cnblogs.com/cnblogs_com/yeshuwei/837768/o_u=733417015,367501698_fm=11_gp=0.jpg",imageLoader);

setImageUrl接收两个参数,第一个是图片的Url地址,第二个为ImageLoader对象。

关于图片加载的目前就学到ImageRequest,ImageLoader,NetworkImageView三种。接下来讲讲自定义的Volley

4.XMLRequest

这里根据郭神的博客跟着学习了一下如何自定义的使用Volley,这里来自顶一个XMLRequest来解析一条XML格式的数据。

打开StringRequest和JsonRequest的源码发现都是继承自Request的并且Request是能够制定泛型类的,这样就能很好的扩张我们想要的东西了。

然后提供了两个有参数的构造方法和两个要重写的抽象方法。这里贴一下源码:

 1 public class StringRequest extends Request<String> {
 2     private final Listener<String> mListener;
 3 
 4     public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) {
 5         super(method, url, errorListener);
 6         this.mListener = listener;
 7     }
 8 
 9     public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {
10         this(0, url, listener, errorListener);
11     }
12 
13     protected void deliverResponse(String response) {
14         this.mListener.onResponse(response);
15     }
16 
17     protected Response<String> parseNetworkResponse(NetworkResponse response) {
18         String parsed;
19         try {
20             parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
21         } catch (UnsupportedEncodingException var4) {
22             parsed = new String(response.data);
23         }
24 
25         return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
26     }
27 }

需要注意的是,在构造函数中一定要调用super()方法将这几个参数传给父类,因为HTTP的请求和响应都是在父类中自动处理的。deliverResponse()方法中的实现很简单,仅仅是调用了mListener中的onResponse()方法,并将response内容传入即可,这样就可以将服务器响应的数据进行回调了。parseNetworkResponse()方法中则应该对服务器响应的数据进行解析,其中数据是以字节的形式存放在NetworkResponse的data变量中的,这里将数据取出然后组装成一个String,并传入Response的success()方法中即可。

详情参考郭神博客:http://blog.csdn.net/guolin_blog/article/details/17612763

下面动手来跟着郭神试试手。

 

 1 public class XMLRequest extends Request<XmlPullParser> {
 2     private final Response.Listener<XmlPullParser> mListener;
 3 
 4     public XMLRequest(int method, String url,Response.Listener<XmlPullParser> listener,
 5                       Response.ErrorListener errorListener) {
 6         super(method, url, errorListener);
 7         this.mListener = listener;
 8     }
 9     public XMLRequest(String url, Response.Listener<XmlPullParser> listener, Response.ErrorListener errorListener) {
10         this(Method.GET, url, listener, errorListener);
11     }
12 
13 
14     /*parseNetworkResponse()方法中则应该对服务器响应的数据进行解析,
15     其中数据是以字节的形式存放在NetworkResponse的data变量中的,
16     这里将数据取出然后组装成一个String,并传入Response的success()方法中即可。*/
17     @Override
18     protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {
19         try {
20             String xmlString=new String(response.data, HttpHeaderParser.parseCharset(response.headers));
21             XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
22             XmlPullParser parser=factory.newPullParser();
23             parser.setInput(new StringReader(xmlString));
24             return Response.success(parser, HttpHeaderParser.parseCacheHeaders(response));
25         } catch (UnsupportedEncodingException e) {
26             return Response.error(new ParseError(e));
27         }catch (XmlPullParserException e) {
28             return Response.error(new ParseError(e));
29         }
30 
31     }
32     /*deliverResponse()方法中的实现很简单,仅仅是调用了mListener中的onResponse()方法,
33     并将response内容传入即可,这样就可以将服务器响应的数据进行回调了。*/
34     @Override
35     protected void deliverResponse(XmlPullParser xmlPullParser) {
36         mListener.onResponse(xmlPullParser);
37     }
38 }

 

下面来尝试用这个XMLRequest来请求一段XML数据

 1 public class xmlRequest extends AppCompatActivity {
 2     private Context context;
 3     private static final String TAG = "xmlRequest";
 4     @Override
 5     protected void onCreate(@Nullable Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         context=getApplicationContext();
 8         RequestQueue mQueue= Volley.newRequestQueue(context);
 9         XMLRequest xmlr=new XMLRequest("http://flash.weather.com.cn/wmaps/xml/china.xml", new Response.Listener<XmlPullParser>() {
10             @Override
11             public void onResponse(XmlPullParser xmlPullParser) {
12                 try {
13                     int eventType=xmlPullParser.getEventType();
14                     while (eventType!=XmlPullParser.END_DOCUMENT){
15                         switch (eventType){
16                             case XmlPullParser.START_TAG:
17                                 String nodename=xmlPullParser.getName();
18                                 if ("city".equals(nodename)){
19                                     String pName=xmlPullParser.getAttributeValue(0);
20                                     Log.d(TAG, "pName is " + pName);
21                                 }
22                                 break;
23                         }
24                         try {
25                             eventType=xmlPullParser.next();
26                         } catch (IOException e) {
27                             e.printStackTrace();
28                         }
29                     }
30                 } catch (XmlPullParserException e) {
31                     e.printStackTrace();
32                 }
33             }
34         }, new Response.ErrorListener() {
35             @Override
36             public void onErrorResponse(VolleyError volleyError) {
37                 Log.e(TAG, volleyError.getMessage(),volleyError );
38             }
39         });
40         mQueue.add(xmlr);
41     }
42 }

其中http://flash.weather.com.cn/wmaps/xml/china.xml是一个用来以XMl格式还回中国所以省份数据的接口。

目前所学就这么些了,参考资料如下:

1.慕课网视频:http://www.imooc.com/learn/468

2.郭神博客:http://blog.csdn.net/guolin_blog?viewmode=contents

3.菜鸟驿站小猪关于XML数据解析讲解:http://www.runoob.com/w3cnote/android-tutorial-xml.html

 

 

RequestQueue mQueue= Volley.newRequestQueue(context);

posted on 2016-06-05 17:53  Swycc  阅读(2177)  评论(0编辑  收藏  举报

导航