A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

JsonObjectRequest

JsonObjectRequest构造方法为:
/**
* @method 请求方式(GET、POST等)
* @url 请求url
* @jsonRequest 请求传入的json数据
* @listener 请求成功回调的接口
* @errorListener 请求失败回调的接口
*/public JsonObjectRequest(int method, String url, JSONObject jsonRequest, Listener<JSONObject> listener, ErrorListener errorListener)

GET

一个完整的JsonObjectRequest的GET请求如下:
因为用的是GET请求方式,参数是在url中传入,所以JSONObject对象传入null
String url = "http://apis.juhe.cn/mobile/get?phone=18270837821&key=9a4329bdf84fa69d193ce601c22b949d";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {
                Toast.makeText(getApplicationContext(),jsonObject.toString(),Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(),volleyError.toString(),Toast.LENGTH_SHORT).show();
            }
        });

        request.setTag("zxy");
        mRequestQueue.add(request);
        mRequestQueue.start();

POST

一个完整的JsonObjectRequest的POST请求如下:
String url = "http://apis.juhe.cn/mobile/get";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("phone", "18270837821");
            jsonObject.put("key", "9a4329bdf84fa69d193ce601c22b949d");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, jsonObject, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {
                Toast.makeText(getApplicationContext(),jsonObject.toString(),Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(),volleyError.toString(),Toast.LENGTH_SHORT).show();
            }
        });
        request.setTag("zxy");
        mRequestQueue.add(request);
        mRequestQueue.start();

用以上StringRequest和JSONObjectRequest请求我们都获取到了数据,如图
这里写图片描述

虽然这两种方式都可以返回我们请求的数据,但是JSONObjectRequest请求在处理json对象的返回结果时候效率更高,所以确定返回结果是json类型时候可以使用JSONObjectRequest

ImageRequest

ImageRequest的构造方法为:
/**
* @url 请求url
* @listener 请求成功回调的接口
* @maxWidth 图片最大的宽度(如果超过则Volley会对图片进行压缩,如果为0则不压缩)
* @maxHeight 图片最大的高度
* @decodeConfig 图片的配置
* @errorListener 请求失败回调的接口
*/public ImageRequest(String url, Listener<Bitmap> listener, int maxWidth, int maxHeight, Config decodeConfig, ErrorListener errorListener)


普通的加载方式(ImageView显示)

一个标准的普通请求网络图片的方法:
String url="http://img.my.csdn.net/uploads/201507/21/1437459520_6685.jpg";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        ImageRequest request = new ImageRequest(url, new Response.Listener<Bitmap>() {
            @Overridepublic void onResponse(Bitmap bitmap) {
                mImageView.setImageBitmap(bitmap);
            }
        }, 0, 0, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
            @Overridepublic void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(),volleyError.toString(),Toast.LENGTH_SHORT).show();
            }
        });
        request.setTag("zxy");
        mRequestQueue.add(request);
        mRequestQueue.start();
    }

这种方式只适合在图片数量不多的情况下使用,否则则需要考虑使用下面两种,同样,因为Volley内部本身就有硬盘缓存机制,在没网的情况下则会加载缓存中的图片

带LruCache缓存的加载方式(ImageView+ImageLoader+ImageCache)

我们上一种方法就是使用Volley中的ImageRequest请求的加载网络图片,这种方法没有LruCache和显示效果不好,下面我们来使用Volley中的ImageLoader+ImageCache的加载方式,这种方式可以在网络差的情况下和加载出错的情况下给出一个默认的提示图片,而且使用了LruCache缓存可以避免OOM。
首先我们创建一个ImageLoader对象,ImageLoader构造方法
public ImageLoader(RequestQueue queue, ImageLoader.ImageCache imageCache)1
1


需要传入请求队列对象和ImageCache对象,我们再来看看ImageCache对象
public interface ImageCache{...}1
1


发现它是ImageLoader内部的一个接口,所以我们得实现这个接口然后传入,于是我们创建一个BimapCache实现ImageCache接口:
public class BitmapCache implements ImageLoader.ImageCache {private LruCache<String, Bitmap> mBitmapLruCache;

    public BitmapCache() {
        int maxCache = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxCache / 8;
        mBitmapLruCache = new LruCache<String, Bitmap>(cacheSize) {
            @Overrideprotected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount();
            }
        };
    }

    @Overridepublic Bitmap getBitmap(String key) {
        return mBitmapLruCache.get(key);
    }

    @Overridepublic void putBitmap(String key, Bitmap bitmap) {
        mBitmapLruCache.put(key, bitmap);
    }
}



其实这就是创建一个图片内存缓存对象。

之后我们再使用ImageLoader.get()方法加载网络图片,我们来看看get()方法的参数:
/**
* @requestUrl - 请求url
* @listener - ImageLoader.ImageListener的监听对象
* @maxWidth - 图片的最大高度,如果超过则会压缩,为0则不压缩
* @maxHeight
*/public ImageLoader.ImageContainer get(String requestUrl, ImageLoader.ImageListener listener, int maxWidth, int maxHeight)


第一个参数好办,那么第二个参数我们可以通过ImageLoader.getImageListener()来得到,我们来看看它的参数:
/**
* @view - 表示将图片设置到哪个控件对象上
* @defaultImageResId- 默认时显示的图片的资源id
* @errorImageResId- 加载出错时显示的图片的资源id
*/public static ImageLoader.ImageListener getImageListener(final ImageView view, final int defaultImageResId, final int errorImageResId)1

好了一切都好办了,一个带LruCache缓存的加载图片的标准请求:
String url="http://img.my.csdn.net/uploads/201507/21/1437459520_6685.jpg";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        ImageLoader mImageLoader = new ImageLoader(mRequestQueue,new BitmapCache());
        ImageLoader.ImageListener imageListener = ImageLoader.getImageListener(mImageView, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
        mImageLoader.get(url,imageListener,0,0);


效果图:
这里写图片描述


【注意】:mImageLoader.get(url,imageListener)加载图片的原理是什么呢?其实从源码中很容易看出,它首先会得到url对应的key,然后判断硬盘缓存中是否含有该key的图片,如果有则取出,没有则通过网络请求重新加载图片,所以使用这种双缓存的方式加载网络图片,可以有效的防止OOM

使用NetworkImageView+ImageLoader+ImageCache

Volley框架中对图片的请求做的特别好,其中还为我们提供了一个专门用于显示图片的控件:NetworkImageView,该控件继承自ImageView,除了拥有ImageView控件的功能之外,还多了三个方法:
public void setImageUrl(String url, ImageLoader imageLoader) {
        this.mUrl = url;
        this.mImageLoader = imageLoader;
        this.loadImageIfNecessary(false);
    }

public void setDefaultImageResId(int defaultImage) {
        this.mDefaultImageId = defaultImage;
    }

public void setErrorImageResId(int errorImage) {
        this.mErrorImageId = errorImage;
    }

1.setDefaultImageResId - 设置该控件默认时显示的图片
2.setErrorImageResId - 设置加载网络图片失败时显示的图片
3.setImageUrl - 从网络上加载图片

使用NetworkImageView需要在layout中替换掉ImageView:
<com.android.volley.toolbox.NetworkImageView
        android:id="@+id/net_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

同样这里也需要使用ImageLoader和ImageCache,一个标准使用NetworkImageView的例子为:
String url="http://img.my.csdn.net/uploads/201507/21/1437459520_6685.jpg";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        ImageLoader mImageLoader = new ImageLoader(mRequestQueue,new BitmapCache());
        mNetworkImageView.setDefaultImageResId(R.mipmap.ic_launcher);//设置默认显示的图片
        mNetworkImageView.setErrorImageResId(R.mipmap.ic_launcher);//设置加载出错时显示的图片
        mNetworkImageView.setImageUrl(url,mImageLoader);


效果为:
这里写图片描述
可以看到用NetworkImageView和第二种方式效果是一样的,它同样会先检查硬盘缓存中有没有该图片,如果没有,再通过网络加载得到该图片,如果有则直接设置。既然和第二种一样,那为什么还推出NetworkImageView这个控件呢?答案就是NetworkImageView这个控件在你的Activity退出时候会自动取消网络请求,即完全不需要我们担心网络请求生命周期的问题。


【注意】:在上述两种使用了LruCache缓存加载图片的方法,当图片量较大时推荐使用,否则当你只有几张图片则使用第一种比较好,因为你使用LruCache时需要为它分配一定的内存空间,而图片量不大时候也使用LruCache缓存,那这块空间则一直是作为缓存图片用的,占着这块内存空间,相反反而会得不偿失。

Volley与Activity生命周期联动与取消请求

其实就是在Activity退出时候或销毁时候,取消对应的网络请求,避免网络请求在后台浪费资源,所以,我们一般在onStop()方法中通过之前设置的Tag取消网络请求:
@Overrideprotected void onStop() {
        super.onStop();
        mRequestQueue.cancelAll("zxy");
    }

RequestQueue.cancelAll()方法会过滤出Tag为“zxy”的所有请求都一并取消。
或者通过Request.cancel()取消请求,把当前Activity的请求放入一个List集合中,关闭Activity时分别取消。

好了,这篇Volley框架的使用篇已经讲完了,下一篇讲Volley的缓存!!!


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马