黑马程序员技术交流社区

标题: Android中的 Volley网络框架完全解析【详解上】 [打印本页]

作者: yezilail    时间: 2016-8-3 10:38
标题: Android中的 Volley网络框架完全解析【详解上】
本帖最后由 yezilail 于 2016-8-3 10:46 编辑

在Android中,网络请求无非就这两种:HttpURLConnection和HttpClient( Apache),我们在使用时一般都会对它们进行一系列的封装,但是这过程不免有些繁琐,所以,Google官方也考虑到了这点,在2013年Google I/O大会上就推出了一个新的网络请求框架——Volley,它将各种网络请求都简单化,并且把AsyncHttpClient和Universal-Image-Loader两大框架的优点集一身,Volley用在数据量不大的网络请求操作时它的性能表现的非常出色,但是Volley如果在进行数据量大的网络操作时(下载文件等),那么Volley将表现的比较糟糕。

关于Volley的架构可以看看这个文章Volley架构

Volley有这么几大功能:


1、普通数据、JSON、图片的异步加载

2、网络请求优先级处理

3、自带硬盘缓存(普通数据、图片、JSON),另外我们在加载图片时候通过ImageLoader还可加入LruCache

4、取消请求

5、与Activity生命周期联动(Activity退出时同时取消所有的请求)

可见,Volley框架是非常强大的,下面我就一一介绍怎么使用Volley框架。


Volley框架的原理:它内部是通过一个请求队列(RequestQueue)来维护所有请求,我们新创建一个请求(request)后通过RequestQueue.add()方法将请求添加置请求队列中,然后调用RequestQueue.start()方法执行请求队列中的方法

Volley中包含这么几种类型的请求:
1.StringRequest - 返回字符串数据
2.JsonObjectRequest - 返回JSONArray数据
3.JsonArrayRequest - 返回JSONObject数据
4.ImageRequest - 返回Bitmap类型数据

当然使用前我们必须导入Volley.jar包(可以去网上下载),或者通过git下载
git clone https://android.googlesource.com/platform/frameworks/volley1
1


这里给出我上传的jar包下载地址:Volley.jar

创建RequestQueue请求队列

RequestQueue是通过Volley的静态方法newRequestQueue来创建的:
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());1
1


一般我们会继承自Application在自定义的MyApplication中创建一个全局的请求队列,用来维护app中的网络请求。

StringRequest

这里主要讲最常用的GET和POST请求方式:
这里我用聚合网上查询手机号码归属地的数据为例子,我们创建一个StringRequest请求,然后给该请求设置一个Tag,用来标记这个请求,取消请求时候我们可以通过这个Tag来取消某个或者所有请求,再把该请求加入请求队列,最后执行请求队列中的请求。

StringRequest的构造方法为:
/**
* @method 请求方式(GET、POST等)
* @url 请求url
* @listener 请求成功回调的接口
* @errorListener 请求失败回调的接口
*/public StringRequest(int method, String url, Listener<String> listener, ErrorListener errorListener)1



GET

一个完整的StringRequest的GET请求如下:
        String url = "http://apis.juhe.cn/mobile/get?phone=18270837821&key=9a4329bdf84fa69d193ce601c22b949d";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());//创建一个请求队列
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(getApplicationContext(),s,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

一个完整的StringRequest的POST请求如下:
String url = "http://apis.juhe.cn/mobile/get";
        RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                Toast.makeText(getApplicationContext(),volleyError.toString(),Toast.LENGTH_SHORT).show();
            }
        }){
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> map  =new HashMap<>();
                map.put("phone","18270837821");
                map.put("key","9a4329bdf84fa69d193ce601c22b949d");
                return map;
            }
        };
        request.setTag("zxy");
        mRequestQueue.add(request);
        mRequestQueue.start();


其中,因为是以POST方式请求数据的,所以我们必须实现StringRequest的getParams()方法,该方法返回的是Map<String, String>类型的集合,也就是用<key,value>的形式把数据通过POST传入服务器

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


作者: yezilail    时间: 2016-8-3 12:21
我的帖子 不帅吗?




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2