Android学习记录之Volley网络通信框架基础解析(1)

这段时间,学习了一些关于网络框架的基础,这里我总结了一下,分享给大家~~
Volley框架由来
我们平时在开发Android应用的时候不可避免地都需要用到网络技术,而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据。Android系统中主要提供了两种方式来进行HTTP通信,HttpURLConnection和HttpClient,几乎在任何项目的代码中我们都能看到这两个类的身影,使用率非常高。
不过HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码。于是乎,一些Android网络通信框架也就应运而生,比如说AsyncHttpClient,它把HTTP所有的通信细节全部封装在了内部,我们只需要简单调用几行代码就可以完成通信操作了。再比如Universal-Image-Loader,它使得在界面上显示网络图片的操作变得极度简单,开发者不用关心如何从网络上获取图片,也不用关心开启线程、回收图片资源等细节,Universal-Image-Loader已经把一切都做好了。
Android开发团队也是意识到了有必要将HTTP的通信操作再进行简单化,于是在2013年Google I/O大会上推出了一个新的网络通信框架——Volley。Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
下图所示的这些应用都是属于数据量不大,但网络通信频繁的,因此非常适合使用Volley。

Volley特点:

通信更快,更简单
get/post网络请求及网络图片的高效率异步处理请求
排序
网络请求的缓存
多级别取消请求
和activity生命周期的联动

功能上:

高效的get/post方式的数据请求交互
网络图片加载和缓存

其他方面:

谷歌官方推出
性能稳定效率强

接下来,我会将volley框架基础的应用分为四个点来讲解一下:
一、volley的get和post请求方式的使用
二、Volley的网络请求队列建立和取消队列请求
三、Volley与Activity生命周期的联动
四、volley的简单的二次回调封装(方便全局管理)

一、volley的get和post请求方式的使用
挑选合适的对象:
StringRequest

这个类可以用来从服务器获取String,如果想自己解析请求响应可以使用这个类,例如返回xml数据。它还可以使用重载的构造函数定制请求。

JsonObjectRequest

这个类可以用来发送和接收JSON对象。这个类的一个重载构造函数允许设置适当的请求方法(DELETE,GET,POST和PUT)。如果您正在使用一个RESTful服务端,可以使用这个类。下面的示例显示如何使GET和POST请求。

JsonArrayRequest

这个类可以用来接受 JSON Arrary,不支持JSON Object。这个类现在只支持 HTTP GET。由于支持GET,你可以在URL的后面加上请求参数。类的构造函数不支持请求参数

回调的使用:

        自定义方法的使用

Get与Post请求方式的区别:

1. get是从服务器上获取数据,post是向服务器传送数据。
2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
4. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
5. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。 

建议:

1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;
2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式;

首先我们建立一个全局的对象,这里我用application来建立这个对象

import android.app.Application;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

/**
 * Created by tim2 on 15/9/14.
 */
public class MyApplication extends Application
{
    //建立全局请求队列
    public static RequestQueue queues;

    @Override
    public void onCreate() {
        super.onCreate();
        //实例化
        queues = Volley.newRequestQueue(getApplicationContext());
    }
    //对外暴露出一个方法,用来获取请求队列
    public static RequestQueue getHttpQueues()
    {
        return queues;
    }
}

建立好后,我们接下来就是在MainActivity中进行操作:
首先是get请求方式,StringRequest对象

//Get请求方式JsonObject
    private void volley_getJson()
    {
        textview.setText("get Json开始了");
        // 错误url:String url = "ip.taobao.com/service/getIpInfo.php?ip=202.96.128.166"
        String url = "http://ip.taobao.com/service/getIpInfo.php?ip=202.96.128.166";
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url,
                new Response.Listener()
                {
                    @Override
                    public void onResponse(JSONObject response) {
                        textview.setText(response.toString());
//                        Toast.makeText(MainActivity.this,response, Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
//                        Toast.makeText(MainActivity.this,error.toString(), Toast.LENGTH_SHORT).show();
                        textview.setText(error.toString());
                    }


                }
        );

        requestTag = "volley_getjson";
        request.setTag(requestTag);
        MyApplication.getHttpQueues().add(request);
    }

Post请求方式,StringRequest对象

private void volley_post()
    {
        textview.setText("post String 开始了");
        // 错误url:String url = "ip.taobao.com/service/getIpInfo.php?ip=202.96.128.166"
        String url = "http://ip.taobao.com/service/getIpInfo.php?";
        StringRequest request = new StringRequest(Request.Method.POST, url,
                new Response.Listener()
                {
                    @Override
                    public void onResponse(String response) {
                        textview.setText(response);
//                        Toast.makeText(MainActivity.this,response, Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
//                        Toast.makeText(MainActivity.this,error.toString(), Toast.LENGTH_SHORT).show();
                        textview.setText(error.toString());
                    }


                }
        ){
            //用户在Volley中使用post方式请求数据中参数的传递
            protected Map getParams() throws AuthFailureError {
                Map hashMap = new HashMap();
                hashMap.put("ip", "202.96.128.166");
                return hashMap;
            }
        };

        requestTag = "volley_post";
        request.setTag(requestTag);
        MyApplication.getHttpQueues().add(request);
    }

Post请求方式,StringRequest对象JsonObjectRequest:

private void volley_postJson()
    {
        textview.setText("post json 开始了");
        Map<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("phone", "13429667914");
        hashMap.put("key", "335adcc4e891ba4e4be6d7534fd54c5d");
        JSONObject jsonParams = new JSONObject(hashMap);
        // 错误url:String url = "ip.taobao.com/service/getIpInfo.php?ip=202.96.128.166"
        String url = "http://apis.juhe.cn/mobile/get?";
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url,jsonParams,
                new Response.Listener<JSONObject>()
                {
                    @Override
                    public void onResponse(JSONObject response) {
                        textview.setText(response.toString());
//                        Toast.makeText(MainActivity.this,response, Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
//                        Toast.makeText(MainActivity.this,error.toString(), Toast.LENGTH_SHORT).show();
                        textview.setText(error.toString());
                    }


                }
        ){

            @Override
            public Map<String, String> getHeaders() {
                HashMap<String, String> headers = new HashMap<String, String>();
                headers.put("Accept", "application/json");
                headers.put("Content-Type", "application/json; charset=UTF-8");

                return headers;
            }


        };

        requestTag = "volley_postjson";
        request.setTag(requestTag);
        MyApplication.getHttpQueues().add(request);
    }

二、Volley的网络请求队列建立和取消队列请求

//添加到队列
MyApplication.getHttpQueues().add(request);
//关闭队列里的所有网络请求
MyApplication.getHttpQueues().cancelAll(requestTag);

三、Volley与Activity生命周期的联动
特点:
可以在activity销毁的时候,同时关闭请求
关键点:
设置Tag标签,onStop()里执行取消请求

在activity生命周期onStop()时执行

    protected void onStop() {
        super.onStop();
        if (!"".equals(requestTag))
        //通过给定的tag值,将制定的队列全部关闭
            MyApplication.getHttpQueues().cancelAll(requestTag);
    }

四、volley的简单的二次回调封装(方便全局管理)
优势:
全局使用一个方式,可控,可自定义定制需求
方便,灵活
主要对于请求成功、或请求失败的一个回调
先建立一个抽象类:

import android.content.Context;

import com.android.volley.Response;
import com.android.volley.VolleyError;

import org.json.JSONException;

/**
 *自定义请求监听抽象类
 * Created by tim2 on 15/9/14.
 */
public abstract class VolleyInterface
{
    public Context context;
    public static Response.Listener listener;
    public static Response.ErrorListener errorListener;

    public abstract void onMySuccess(String result);
    public abstract  void onMyError(VolleyError error);

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

    public Response.Listener loadingListener()
    {
        listener = new Response.Listener() {
            @Override
            public void onResponse(String response) {
                onMySuccess(response);
            }
        };
        return listener;
    }

    public Response.ErrorListener errorListener()
    {
        errorListener = new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                onMyError(error);
            }
        };
        return errorListener;
    }
}

对于get与post分别的封装

mport android.content.Context;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.toolbox.StringRequest;
import com.timliu.volleyactivity.MyApplication;

import java.util.Map;

/**
 * Created by tim2 on 15/9/14.
 */
public class VolleyRequest
{
    public static StringRequest stringRequest;
    public static Context context;

    public static void RequestGet(Context context,String url, String tag, VolleyInterface vif)
    {
        //在请求之前,先把全部的tag取消掉,防止重复的请求,来消耗内存
        MyApplication.getHttpQueues().cancelAll(tag);
        stringRequest = new StringRequest(Request.Method.GET,url,vif.loadingListener(),vif.errorListener());
        stringRequest.setTag(tag);
        MyApplication.getHttpQueues().add(stringRequest);
        // 不写也能执行
//        MyApplication.getHttpQueues().start();
    }

    public static void RequestPost(Context context,String url, String tag,final Map params, VolleyInterface vif)
    {
        MyApplication.getHttpQueues().cancelAll(tag);
        stringRequest = new StringRequest(Request.Method.POST,url,vif.loadingListener(),vif.errorListener())
        {
            @Override
            protected Map getParams() throws AuthFailureError {
                return params;
            }
        };
        stringRequest.setTag(tag);
        MyApplication.getHttpQueues().add(stringRequest);
        // 不写也能执行
//        MyApplication.getHttpQueues().start();
    }
}

你可能感兴趣的:(学习记录)