• 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);
  • 相关阅读:
    屏幕录像大师2016【破解版】
    Hibernate demo之使用注解
    Hibernate demo之使用xml
    Hibernate 的<generator class="native"></generator>的不同属性含义
    java 动态实现接口
    c# emit 实现类的代理
    c# emit 动态实现接口
    java nio读取和写入文件
    java 读取Properties
    Java中利用MessageFormat对象实现类似C# string.Format方法格式化
  • 原文地址:https://www.cnblogs.com/yeshuwei/p/5561284.html
Copyright © 2020-2023  润新知