背景
这个礼拜要整个演示的Android项目,正好web服务端提供了restful形式的接口,就趁这个演示项目尝试一下谷歌官方的网络通讯框架Volley,时间有限,只有先做到会用了。了解到有这个框架是之前在看官网的Training的时候留意到的(http://developer.android.com/training/volley/index.html),因为Volley是把所有的网络响应都放在内存里面解析的,所以不适合大数据的下载和流操作。下面就是结合官网文档的一些使用情况。
添加依赖
可以通过git下载Volley的源码
git clone https://android.googlesource.com/platform/frameworks/volley
然后可以直接当成Android Library project引入也可以编译成jar包的形式引入。
我这里因为用的是Android Studio,我这个为了快(懒),在github上有跟官方同步的Volley源码,可以直接在build.gradle里面添加compile 'com.mcxiaoke.volley:library:1.0.+',然后在Tools->Android->Sync Project with Gradle Files,等处理完就完成了导入
简单的发送和取消请求
添加权限
<uses-permission android:name="android.permission.INTERNET"/>
发送请求:
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://www.baidu.com"; //注意别漏掉http://
StringRequest stringRequest = new StringRequest(Request.Method.GET,url,new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i(TAG,response);
}
},new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG,error.getLocalizedMessage());
}
});
queue.add(stringRequest);
运行这段代码,如果手机联网的话就可以看到返回的百度首页的html
取消请求:
stringRequest.setTag(TAG);
可以给request设置tag,然后在activity的onStop方法里取消所有包含这个TAG的请求
@Override
protected void onStop() {
super.onStop();
if (queue != null) {
queue.cancelAll(TAG);
}
}
设置Volley的网络和缓存实现
上面的步骤只是简单的使用
来生成请求队列的实例,使用的都是Volley默认的网络和缓存实现,Volley还允许我们自己设置网络和缓存的实现
RequestQueue queue = Volley.newRequestQueue(this);
//定义cache和网络的实现
Cache cache = new DiskBasedCache(getCacheDir(),1024*1024); //1M cache
Network network = new BasicNetwork(new HurlStack()); //使用的HttpURLConnection 支持API 9及以上
queue = new RequestQueue(cache,network);
queue.start();
String url = "http://www.baidu.com";
StringRequest stringRequest = new StringRequest(Request.Method.GET,url,new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i(TAG,response);
}
},new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG,error.toString());
}
});
stringRequest.setTag(TAG);
queue.add(stringRequest);
Volley单例调用
如果项目中不同的地方需要频繁的调用Volley的网络请求,我们为了不重复创建很多的RequestQueue对象,可以把Volley的调用封装成一个单例模式,网上看到有直接写在自己实现的Application子类里面,Google官网建议直接写个单例类,这样做更灵活清晰,下面一个最简单的单例类
public class VolleySingleton {
private static VolleySingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mContext;
private VolleySingleton(Context context){
mContext = context;
mRequestQueue = getRequestQueue();
}
public static synchronized VolleySingleton getInstance(Context context){
if (mInstance == null){
mInstance = new VolleySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue(){
if(mRequestQueue == null){
//这里是关键,能确保mRequestQueue的生命周期与你的app一样
mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> request){
getRequestQueue().add(request);
}
}
调用这个单例类的实例
VolleySingleton.getInstance(this).getRequestQueue().add(xxxRequest);//发送请求
VolleySingleton.getInstance(this.getApplication()).getRequestQueue().cancelAll(TAG);//取消请求
一些其他类型的request
最常用的当然是JsonObjectRequest和JsonArrayRequest,暂时没用到图片,所以这里就先不写图片的请求了,Volley提供了专门用于图片请求的ImageRequest对象
JsonObjectRequest的使用
JSONObject object = new JSONObject(); //请求的参数的json对象
object.put("recordId",recordId);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,"请求的url",object,new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i(TAG,"response:"+response); //请求成功返回的json数据
}
},new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG,error.toString());
}
});
jsObjRequest.setTag(TAG);
VolleySingleton.getInstance(this).getRequestQueue().add(jsObjRequest);
JsonArrayRequest的使用
JsonArrayRequest jsArrayRequest = new JsonArrayRequest(url,new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.i(TAG,"load record response:"+response);
}
},new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG,error.toString());
}
});
jsArrayRequest.setTag(TAG);
VolleySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
自定义request
正常情况下直接用Volley提供的request实现即可,但是在某些情况下我们可能需要实现自己的request,比如Volley默认使用的JsonObjectRequest使用的是Android自带的JsonObject类,而这个处理json的类效率不如第三方的json处理类,为了效率,我们可能就需要实现自己的request类了,实现的方法也很简单,1、继承Request<T>这个抽象类,既然是抽象类,就有需要我们实现的抽象方法,2、实现deliverResponse和parseNetworkResponse这两个抽象方法。(可以参考下JsonObjectRequest等几个Volley的实现方法)这里直接贴一个官网用Gson实现的GsonRequest类
public class GsonRequest<T> extends Request<T>{
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String,String> headers;
private final Response.Listener<T> listener;
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response){
try {
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(gson.fromJson(json,clazz),HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
}
这样就可以用我们自己实现的GsonRequest和自定义的T类来把请求的数据生成json对象了
补充下gradle导入Gson依赖,在build.gradle中添加compile 'com.google.code.gson:gson:2.3.1'就行了
结尾
写到这里我用的Volley的基本功能就写完了,当然想用好这个框架光知道这么多试远远不够的,等这周过完还会再仔细的看下Volley这个框架,后续博客还会补上更详细的细节