最简单详细的Volley使用解析

十分详细又浅显易懂的Volley使用解析。

完整代码已上传到github,需要的可以自行download或者clone。

Volley是Android网络开发过程中十分重要的一个网络框架,基本都会用到,在这里总结一下Volley的特点和使用过程中需要注意的一些问题。

一、Volley特点:

1). 自动调度网络请求

2). 多个并发的网络连接----一个缓存线程,4个网络线程

3). 高效的Get/Post数据请求交互;

4). 网络图片加载和缓存;

5). 谷歌官方推出的,性能也比较稳定。

6). 特别适合数据量小,通信频繁的网络操作

图片加载效率一般

二、Volley的基本使用:

1. get和post请求

    对象:StringRequest、JsonObjectRequest、JsonArrayRequest。根据数据类型选择合适的对象,一般StringRequest包含JsonObjectRequest、JsonArrayRequest这两种对象。

    回调:两个接口Listener和ErrorListener

2. Volley的网络请求队列建立和取消队列请求

    建立请求队列

    取消某个请求或者所有请求

3. Volley与Activity生命周期的联动

    特点:可以在Activity被销毁的同时关闭请求

    关键点:设置Tag标签,onStop()方法中执行取消操作

4. Volley的简单二次回调封装

    全局使用一个方式,可控,可自定义定制需求,方便,灵活

5. 使用ImageRequest获取网络图片

    通过创建ImageRequest对象,传入url和Listener回调接口,最后显示图片

6. 使用ImageLoader缓存加载网络图片

    通过ImageLoader、ImageListener、ImageCache或者LruCache来完成

三、Volley的详细使用

    为了防止资源浪费,在Application中定义RequestQueue,并提供一个getQueues()方法,返回RequestQueue对象。

public class MyApplication extends Application {
    public static RequestQueue queues;

    @Override
    public void onCreate() {
        super.onCreate();
        queues = Volley.newRequestQueue(getApplicationContext());
    }

    public static RequestQueue getQueues() {
        return queues;
    }
}

1. get请求    

    1) 使用StringRequest获取网络数据

private void volleyGet() {
        //通过StringRequest获取
        String url = "自己想要访问的网络数据的url";
        StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
            }
        });
        request.setTag("StringRequestGet");
        MyApplication.getQueues().add(request);
}

2) 使用JsonObjectRequest获取网络数据

private void volleyGet() {        
        String url = "自己想要访问的网络数据的url";
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {
                Toast.makeText(MainActivity.this, jsonObject.toString(), Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
            }
        });
        request.setTag("JsonObjectStringGet");
        MyApplication.getQueues().add(request);
}

3) 使用JsonArrayRequest获取网络数据

private void volleyGet() {  
        String url = "自己想要访问的网络数据的url";
        JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray jsonArray) {
                Toast.makeText(MainActivity.this, jsonArray.toString(), Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
            }
        });
        request.setTag("JsonObjectStringGet");
        MyApplication.getQueues().add(request);
}

其实使用StringRequest、JsonObjectRequest或者JsonArrayRequest取决于网络数据的格式,一般可以直接使用StringRequest获取,再对获取到的数据进行处理,对于Json格式的数据使用JsonObjectRequest效率能高一点,Array类型的数据类似。

2. post请求

    1) 使用StringRequest网络数据获取

private void volleyPost() {
        String url = "自己想要访问的网络数据的url";
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> hashMap = new HashMap<>();
                hashMap.put("key", "value");
                return hashMap;
            }
        };
        request.setTag("StringRequestPost");
        MyApplication.getQueues().add(request);
}

2) 使用JsonObjectRequest获取网络数据

    使用过程中遇到的最大的一个坑就是,在post传参的时候使用的是HashMap,然后就HashMap转换成JsonObject对象,但是,要考虑到服务器是否能接受Json格式的数据,否则就是获取不到数据。

    a. 服务器支持Json格式

private void volleyPost() {
        String url = "http://apis.juhe.cn/mobile/get?";
        Map<String, String> hashMap = new HashMap<>();
        hashMap.put("key", "value");
        JSONObject object = new JSONObject(hashMap);
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, object, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject jsonObject) {
                Log.i("TAG",jsonObject.toString());
                Toast.makeText(MainActivity.this, jsonObject.toString(), Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(MainActivity.this, volleyError.toString(), Toast.LENGTH_SHORT).show();
            }
        });
        request.setTag("Post");
        MyApplication.getQueues().add(request);
}

b. 服务器不支持Json格式的数据

    说实话,从网上找的解决办法,有两种,第一种是将传入的url直接写成String类型,经过自定义JsonObjectRequest来实现,呵呵,没有用的;第二种就是在JsonObjectRequest中定义和重写一大堆乱七八糟的代码,看不懂,没用,总而言之,Google推出这个Volley,能不能封装好了给我们来使用,看了一大堆源码和解决方法还是没有用,建议不要使用JsonObjectRequest,直接使用StringRequest。

3. Volley和Activity的联动

    在onStop()方法中处理

protected void onStop() {
        super.onStop();
        MyApplication.getQueues().cancelAll("Get");
        MyApplication.getQueues().cancelAll("Post");
}

4. Volley的简单二次封装

    对Volley的封装主要就是三步:以StringRequest为例

    第一步 封装两个回调接口Listener和ErrorListener,并添加两个抽象方法,方便重写。如下

public abstract class VolleyInterface {
    public Context mContext;
    public static Response.Listener listener;
    public static Response.ErrorListener errorListener;

    public abstract void onSuccess(Object result);
    public abstract void onError(VolleyError result);

    public VolleyInterface(Context mContext, Response.Listener listener, Response.ErrorListener errorListener) {
        this.mContext = mContext;
        this.listener = listener;
        this.errorListener = errorListener;
    }

    //成功时回调的接口,同时调用onSuccess()方法
    public Response.Listener succeedListener(){
        listener = new Response.Listener() {
            @Override
            public void onResponse(Object response) {
                onSuccess(response);
            }
        };
        return listener;
    }

    //失败时回调的接口,同时调用errorListener()方法
    public Response.ErrorListener errorListener(){
        errorListener = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                onError(error);
            }
        };
        return errorListener;
    }
}

    第二步 封装VolleyRequest请求

public class VolleyRequest {
    public static StringRequest request;
    public static Context mContext;

    public static void RequestGet(Context mContext, String url, String tag,VolleyInterface vif) {
        MyApplication.getQueues().cancelAll(tag);
        //创建StringRequest对象时,传入两个回调接口
        request = new StringRequest(Request.Method.GET, url, vif.succeedListener(),vif.errorListener);
        request.setTag(tag);
        MyApplication.getQueues().add(request);
    }

    public static void RequestPost(Context mContext, String url, String tag, final Map<String,String> params, VolleyInterface vif) {
        MyApplication.getQueues().cancelAll(tag);
        //创建StringRequest对象时,传入两个回调接口,以及重写getParams()方法
        request = new StringRequest(Request.Method.POST,url,vif.succeedListener(),vif.errorListener){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                return params;
            }
        };
        request.setTag(tag);
        MyApplication.getQueues().add(request);
    }
}

    第三步 在Activity中使用封装好的类来访问数据

String url = "自己想要访问的网络数据的url";
    VolleyRequest.RequestGet(this, url, "Get", new VolleyInterface(this,VolleyInterface.listener,VolleyInterface.errorListener) {
        @Override
        public void onSuccess(Object result) {
            Toast.makeText(MainActivity.this, result.toString(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onError(VolleyError result) {
            Toast.makeText(MainActivity.this, result.toString(), Toast.LENGTH_SHORT).show();
        }
    });

5. 使用ImageRequest获取网络图片

    这个简单,通过创建ImageRequest对象,传入url和Listener回调接口,最后显示图片

    String url = "https://ws1.sinaimg.cn/large/0065oQSqly1fuo54a6p0uj30sg0zdqnf.jpg";
    ImageRequest imageRequest = new ImageRequest(url, new Response.Listener<Bitmap>() {
        @Override
        public void onResponse(Bitmap response) {
            imageView.setImageBitmap(response);
        }
    }, width, height, Bitmap.Config.RGB_565, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
        }
    });
    imageRequest.setTag("image");
    MyApplication.getQueues().add(imageRequest);

6. 使用ImageLoader缓存网络图片

    通过ImageLoader、ImageListener、ImageCache或者LruCache来完成。

    String url = "https://ws1.sinaimg.cn/large/0065oQSqly1fuo54a6p0uj30sg0zdqnf.jpg";
    ImageLoader loader = new ImageLoader(MyApplication.getQueues(),new BitmapCache());
    ImageLoader.ImageListener listener =          ImageLoader.getImageListener(imageView,R.mipmap.ic_launcher,R.mipmap.ic_launcher);
    loader.get(url,listener);

    还可以使用Volley自带的NetworkImageView

    String url = "https://ws1.sinaimg.cn/large/0065oQSqly1fuo54a6p0uj30sg0zdqnf.jpg";
    ImageLoader loader = new ImageLoader(MyApplication.getQueues(),new BitmapCache());
    networkImageView.setDefaultImageResId(R.mipmip.ic_launcher);
    networkImageView.setImageUrl(url,loader);

大功告成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值