成功的信念在人脑中的作用就如闹钟,会在你需要时将你唤醒。
本讲内容:网络通信框架——Volley
一、Volley介绍
由于HTTP的通信操作太过于复杂,于是在2013年Google I/O大会上推出了一个新的网络通信框架——Volley。Volley适合去进行数据量不大,但通信频繁的网络操作(不适合上传和下载)。
二、Volley的Get和Post请求方式的使用(HTTP的请求类型通常有两种,GET和POST)
Volley自带的三种合适的请求对象
StringRequest 对请求的数据返回的结果类型不确定的时候使用(包含下面二种,效率比较低)
JsonObjectRequest对请求的数据返回的结果类型是JsonObject的时候使用
JsonArrayRequest 对请求的数据返回的结果类型是JsonArray的时候使用
StringRequest,JsonRequest继承自Request类的,不过由于JsonRequest是一个抽象类,因此我们无法直接创建它的实例。JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayReques。一个是用于请求一段JSON数据的,一个是用于请求一段JSON数组的。
示例一:Volley的Get方式请求数据(发起一条HTTP请求,然后接收HTTP响应)
使用步骤:
1、获取一个RequestQueue请求队列对象,它可以缓存所有的HTTP请求,然后按照一定的算法并发地发出这些请求。
RequestQueue mQueue=Volley.newRequestQueue(context);
2、创建一个StringRequest对象,StringRequest的构造函数需要传入三个参数(与四个参数的一样,第一个参数默认是Method.GET请求类型),第一个参数就是目标服务器的URL地址,第二个参数是服务器响应成功的回调,第三个参数是服务器响应失败的回调。
3、将这个StringRequest对象添加到RequestQueue里面
4、AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
下面是app.java主界面文件:
public class app extends Application{
//Volley的网络请求队列是全局变量,方便把volley的请求和程序的生命周期绑定起来
public static RequestQueue queues;
public void onCreate() {
super.onCreate();
//获取一个RequestQueue请求队列对象(全局上下文)
queues=Volley.newRequestQueue(getApplicationContext());
}
/**
* 获取请求队列方法
*/
public static RequestQueue getHttpQueues(){
return queues;
}
}
看到这里你可能会有疑问,为什么已经public了,为什么还要get?
因为方便在这个方法里可以加入其他自定义,例如判断这个队列是否为空,为空就重新新建对象。
不忘了在清单文件中写
<application
android:name="com.example.volleydemo.app"
…… >
下面是MainActivity.java界面文件:
public class MainActivity extends Activity {
private static final String TAG="tag";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volley_Get();
}
/**
* Volley的Get方式请求数据方法
*/
private void volley_Get() {
String url="http://www.baidu.com";
StringRequest request=new StringRequest(Method.GET, url, new Response.Listener<String>() {
public void onResponse(String response) {
Log.d(TAG, response);
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(),error);
}
});
//为请求对象设置一个标签,方便加入全局队列后可以通过这个标签进行查找
request.setTag("Get01");
//将这个请求对象加入全局队列
app.getHttpQueues().add(request);
}
}
运行程序 就会看到LogCat中会打印服务器响应的数据
使用JsonObjectRequest请求对象。
public class MainActivity extends Activity {
private static final String TAG="tag";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volley_Get();
}
/**
* Volley的Get方式请求数据方法
*/
private void volley_Get() {
String url="http://www.weather.com.cn/data/sk/101010100.html";
JsonObjectRequest request=new JsonObjectRequest(Method.GET, url, null, new Response.Listener<JSONObject>() {
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(),error);
}
});
request.setTag("Get01");
app.getHttpQueues().add(request);
}
}
这里我们填写的URL地址是http://www.weather.com.cn/data/sk/101010100.html,这是中国天气网提供的一个查询天气信息的接口,响应的数据就是以JSON格式返回的,第三个参数是请求对象,因为我们使用Get的方式,这里写null即可。
运行程序就会看到LogCat中会打印服务器响应的数据
示例二:Volley的Post方式请求数据
下面是MainActivity.java界面文件:
public class MainActivity extends Activity {
private static final String TAG="tag";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volley_Post();
}
/**
* Volley的Post方式请求数据方法
*/
private void volley_Post() {
//http://tieba.baidu.com/home/main?id=2766c7dab7dcb5c4d1f4b9e2b1dabba29e40&fr=userbar
String url="http://tieba.baidu.com/home/main?";
StringRequest request=new StringRequest(Method.POST, url, new Response.Listener<String>() {
public void onResponse(String response) {
Log.d(TAG, response);
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(),error);
}
}){
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put("id", "2766c7dab7dcb5c4d1f4b9e2b1dabba29e40");
map.put("fr", "userbar");
return map;
}
};
request.setTag("Post01");
app.getHttpQueues().add(request);
}
}
这里指定了HTTP请求方式是POST,那么我们要提交给服务器的参数又该怎么设置呢?很遗憾,StringRequest中并没有提供设置POST参数的方法,但是当发出POST请求的时候,Volley会尝试调用StringRequest的父类——Request中的getParams()方法来获取POST参数,所以我们只需要在StringRequest的匿名类中重写getParams()方法,在这里设置POST参数就可以了。
运行程序就会看到LogCat中会打印服务器响应的数据
使用JsonObjectRequest请求对象。
public class MainActivity extends Activity {
private static final String TAG="tag";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volley_Post();
}
/**
* Volley的Post方式请求数据方法
*/
private void volley_Post() {
String url="http://tieba.baidu.com/home/main?";
Map<String, String> map = new HashMap<String, String>();
map.put("id", "2766c7dab7dcb5c4d1f4b9e2b1dabba29e40");
map.put("fr", "userbar");
JSONObject object=new JSONObject(map);
JsonObjectRequest request=new JsonObjectRequest(Method.GET, url, object, new Response.Listener<JSONObject>() {
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
Log.e(TAG, error.getMessage(),error);
}
});
request.setTag("Post01");
app.getHttpQueues().add(request);
}
}
三、Volley与Activity生命周期的联动
//cancelAll()方法:通过给定的tag值,将指定的队列全部关闭。
protected void onStop() {
super.onStop();
app.getHttpQueues().cancelAll("Get01");
}
四、Volley的简单的二次回调封装
下面是VolleyInterface.java文件:
public abstract class VolleyInterface {
private static final String TAG="tag";
public Context mContext;
public static Listener<String> mListener;
public static ErrorListener mErrorListener;
public VolleyInterface(Context context, Listener<String> listener,
ErrorListener errorListener) {
this.mContext = context;
this.mListener = listener;
this.mErrorListener = errorListener;
}
public abstract void onMySuccess(String result);
public abstract void onMyError(VolleyError error);
/**
* 请求成功的回调方法
*/
public Listener<String> loadingListener(){
mListener=new Listener<String>(){
public void onResponse(String response) {
onMySuccess(response);
Log.d(TAG, response);
}
};
return mListener;
}
public ErrorListener errorListener(){
mErrorListener=new ErrorListener() {
public void onErrorResponse(VolleyError error) {
onMyError(error);
Log.e(TAG, error.getMessage(),error);
}
};
return mErrorListener;
}
}
下面是 VolleyRequest .java文件:
public class VolleyRequest {
public static StringRequest stringRequest;
public static Context context;
public static void RequestGet(Context mContext,String url,String tag,VolleyInterface vif){
app.getHttpQueues().cancelAll(tag);//防止重复的请求,浪费内存
stringRequest=new StringRequest(Method.GET, url, vif.loadingListener(), vif.errorListener());
stringRequest.setTag("Get01");
app.getHttpQueues().add(stringRequest);
app.getHttpQueues().start();
}
public static void RequestPost(Context mContext,String url,String tag,
final Map<String,String> params,VolleyInterface vif){
app.getHttpQueues().cancelAll(tag);
stringRequest=new StringRequest(url, vif.loadingListener(), vif.errorListener()){
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
};
stringRequest.setTag("Post01");
app.getHttpQueues().add(stringRequest);
app.getHttpQueues().start();
}
}
下面是 MainActivity .java文件:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volley_Get();
}
protected void onStop() {
super.onStop();
app.getHttpQueues().cancelAll("Get01");
}
/**
* Volley的Post方式请求数据方法
*/
private void volley_Get() {
String url="http://www.baidu.com";
VolleyRequest.RequestGet(this, url, "Get01", new VolleyInterface(this,VolleyInterface.mListener,VolleyInterface.mErrorListener) {
public void onMySuccess(String result) {
}
public void onMyError(VolleyError error) {
}
});
}
}
运行的结果是一样的,用封装的方法是不是简单多了。