Android Volley完全解析*

Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。

1. StringRequest的用法

权限<uses-permission android:name="android.permission.INTERNET" />  

主要就是进行了以下三步操作:

1. 创建一个RequestQueue对象。

RequestQueue mQueue = Volley.newRequestQueue(context);  

2. 创建一个StringRequest对象。

StringRequest stringRequest = new StringRequest("http://www.baidu.com",  
                        new Response.Listener<String>() {  
                            @Override  
                            public void onResponse(String response) {  
                                Log.d("TAG", response);  
                            }  
                        }, new Response.ErrorListener() {  
                            @Override  
                            public void onErrorResponse(VolleyError error) {  
                                Log.e("TAG", error.getMessage(), error);  
                            }  
                        });  

3. 将StringRequest对象添加到RequestQueue里面。

mQueue.add(stringRequest);  

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;  
    }  
};

4. JsonRequest的用法


JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayRequest 

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("http://m.weather.com.cn/data/101010100.html", null,  
        new Response.Listener<JSONObject>() {  
            @Override  
            public void onResponse(JSONObject response) {  
                Log.d("TAG", response.toString());  
            }  
        }, new Response.ErrorListener() {  
            @Override  
            public void onErrorResponse(VolleyError error) {  
                Log.e("TAG", error.getMessage(), error);  
            }  
        });  

mQueue.add(jsonObjectRequest); 

5. ImageRequest的用法

ImageRequest imageRequest = new ImageRequest(  
        "http://developer.android.com/images/home/aw_dac.png",  
        new Response.Listener<Bitmap>() {  
            @Override  
            public void onResponse(Bitmap response) {  
                imageView.setImageBitmap(response);  
            }  
        }, 0, 0, Config.RGB_565, new Response.ErrorListener() {  
            @Override  
            public void onErrorResponse(VolleyError error) {  
                imageView.setImageResource(R.drawable.default_image);  
            }  
        });  

  mQueue.add(imageRequest);  

ImageRequest的构造函数接收六个参数,第一个参数就是图片的URL地址。第二个参数是图片请求成功的回调。第三第四个参数分别用于指定允许图片最大的宽度和高度,如果指定的网络图片的宽度或高度大于这里的最大值,则会对图片进行压缩,指定成0的话就表示不管图片有多大,都不会进行压缩。第五个参数用于指定图片的颜色属性,Bitmap.Config下的几个常量都可以在这里使用,其中ARGB_8888可以展示最好的颜色属性,每个图片像素占据4个字节的大小,而RGB_565则表示每个图片像素占据2个字节大小。第六个参数是图片请求失败的回调,这里我们当请求失败时在ImageView中显示一张默认图片。

6. ImageLoader的用法

新建BitmapCache实现ImageCache接口,如下所示:

public class BitmapCache implements ImageCache {  
    private LruCache<String, Bitmap> mCache;  
    public BitmapCache() {  
        int maxSize = 10 * 1024 * 1024;  
        mCache = new LruCache<String, Bitmap>(maxSize) {  
            @Override  
            protected int sizeOf(String key, Bitmap bitmap) {  
                return bitmap.getRowBytes() * bitmap.getHeight();  
            }  
        };  
    }  
  
    @Override  
    public Bitmap getBitmap(String url) {  
        return mCache.get(url);  
    }  
  
    @Override  
    public void putBitmap(String url, Bitmap bitmap) {  
        mCache.put(url, bitmap);  
    }  
}  
  ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache()); 
  ImageListener listener = ImageLoader.getImageListener(imageView, R.drawable.default_image,R.drawable.failed_image); 
  imageLoader.get("http://img.my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener); 
  imageLoader.get("http://img.my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", listener, 200, 200); 

7. NetworkImageView的用法

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:orientation="vertical" >  
  
    <Button  
        android:id="@+id/button"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Send Request" />  
      
    <com.android.volley.toolbox.NetworkImageView   
        android:id="@+id/network_image_view"  
        android:layout_width="200dp"  
        android:layout_height="200dp"  
        android:layout_gravity="center_horizontal"  
        />  
  
</LinearLayout>  

  networkImageView = (NetworkImageView) findViewById(R.id.network_image_view);  

networkImageView.setDefaultImageResId(R.drawable.default_image);  
networkImageView.setErrorImageResId(R.drawable.failed_image);  
networkImageView.setImageUrl("http://img.my.csdn.net/uploads/201404/13/1397393290_5765.jpeg", imageLoader);  

 NetworkImageView并不需要提供任何设置最大宽高的方法也能够对加载的图片进行压缩。这是由于NetworkImageView是一个控件,在加载图片的时候它会自动获取自身的宽高,然后对比网络图片的宽度,再决定是否需要对图片进行压缩。也就是说,压缩过程是在内部完全自动化的,并不需要我们关心,NetworkImageView会始终呈现给我们一张大小刚刚好的网络图片,不会多占用任何一点内存,这也是NetworkImageView最简单好用的一点吧。

不想对图片进行压缩的话,只需要在布局文件中把NetworkImageView的layout_width和layout_height都设置成wrap_content就可以了,这样NetworkImageView就会将该图片的原始大小展示出来,不会进行任何压缩。

 自定义XMLRequest

参照StringRequest的实现原理

public class XMLRequest extends Request<XmlPullParser> {  
  
    private final Listener<XmlPullParser> mListener;  
  
    public XMLRequest(int method, String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {  
        super(method, url, errorListener);  
        mListener = listener;  
    }  
  
    public XMLRequest(String url, Listener<XmlPullParser> listener, ErrorListener errorListener) {  
        this(Method.GET, url, listener, errorListener);  
    }  
  
    @Override  
    protected Response<XmlPullParser> parseNetworkResponse(NetworkResponse response) {  
        try {  
            String xmlString = new String(response.data,HttpHeaderParser.parseCharset(response.headers));  
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
            XmlPullParser xmlPullParser = factory.newPullParser();  
            xmlPullParser.setInput(new StringReader(xmlString));  
            return Response.success(xmlPullParser, HttpHeaderParser.parseCacheHeaders(response));  
        } catch (UnsupportedEncodingException e) {  
            return Response.error(new ParseError(e));  
        } catch (XmlPullParserException e) {  
            return Response.error(new ParseError(e));  
        }  
    }  
  
    @Override  
    protected void deliverResponse(XmlPullParser response) {  
        mListener.onResponse(response);  
    }  
}  
XMLRequest xmlRequest = new XMLRequest("http://flash.weather.com.cn/wmaps/xml/china.xml",new Response.Listener<XmlPullParser>() {  
            @Override  
            public void onResponse(XmlPullParser response) {  
                try {  
                    int eventType = response.getEventType();  
                    while (eventType != XmlPullParser.END_DOCUMENT) {  
                        switch (eventType) {  
                        case XmlPullParser.START_TAG:  
                            String nodeName = response.getName();  
                            if ("city".equals(nodeName)) {  
                                String pName = response.getAttributeValue(0);  
                                Log.d("TAG", "pName is " + pName);  
                            }  
                            break;  
                        }  
                        eventType = response.next();  
                    }  
                } catch (XmlPullParserException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }, new Response.ErrorListener() {  
            @Override  
            public void onErrorResponse(VolleyError error) {  
                Log.e("TAG", error.getMessage(), error);  
            }  
        });  
mQueue.add(xmlRequest);  

2. 自定义GsonRequest

public class GsonRequest<T> extends Request<T> {  
  
    private final Listener<T> mListener;  
  
    private Gson mGson;  
  
    private Class<T> mClass;  
  
    public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {  
        super(method, url, errorListener);  
        mGson = new Gson();  
        mClass = clazz;  
        mListener = listener;  
    }  
  
    public GsonRequest(String url, Class<T> clazz, Listener<T> listener, ErrorListener errorListener) {  
        this(Method.GET, url, clazz, listener, errorListener);  
    }  
  
    @Override  
    protected Response<T> parseNetworkResponse(NetworkResponse response) {  
        try {  
            String jsonString = new String(response.data,HttpHeaderParser.parseCharset(response.headers));  
            return Response.success(mGson.fromJson(jsonString, mClass),HttpHeaderParser.parseCacheHeaders(response));  
        } catch (UnsupportedEncodingException e) {  
            return Response.error(new ParseError(e));  
        }  
    }  
  
    @Override  
    protected void deliverResponse(T response) {  
        mListener.onResponse(response);  
    }  
  
}  
public class Weather {  
  
    private WeatherInfo weatherinfo;  
  
    public WeatherInfo getWeatherinfo() {  
        return weatherinfo;  
    }  
  
    public void setWeatherinfo(WeatherInfo weatherinfo) {  
        this.weatherinfo = weatherinfo;  
    }  
  
}  
public class WeatherInfo {  
  
    private String city;  
  
    private String temp;  
  
    private String time;  
  
    public String getCity() {  
        return city;  
    }  
  
    public void setCity(String city) {  
        this.city = city;  
    }  
  
    public String getTemp() {  
        return temp;  
    }  
  
    public void setTemp(String temp) {  
        this.temp = temp;  
    }  
  
    public String getTime() {  
        return time;  
    }  
  
    public void setTime(String time) {  
        this.time = time;  
    }  
  
}  
GsonRequest<Weather> gsonRequest = new GsonRequest<Weather>("http://www.weather.com.cn/data/sk/101010100.html", Weather.class,new Response.Listener<Weather>() {  
            @Override  
            public void onResponse(Weather weather) {  
                WeatherInfo weatherInfo = weather.getWeatherinfo();  
                Log.d("TAG", "city is " + weatherInfo.getCity());  
                Log.d("TAG", "temp is " + weatherInfo.getTemp());  
                Log.d("TAG", "time is " + weatherInfo.getTime());  
            }  
        }, new Response.ErrorListener() {  
            @Override  
            public void onErrorResponse(VolleyError error) {  
                Log.e("TAG", error.getMessage(), error);  
            }  
        });  
mQueue.add(gsonRequest);  
原文地址:https://www.cnblogs.com/chenxibobo/p/6136743.html