这段时间,学习了一些关于网络框架的基础,这里我总结了一下,分享给大家~~
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();
}
}