在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,今年的Google I/O 2013上,Volley发布了。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。
Volley主页 https://android.googlesource.com/platform/frameworks/volley
http://www.youtube.com/watch?v=yhv8l9F44qo&feature=player_embedded
优势:
· JSON,图像等的异步下载;
· 网络请求的排序(scheduling)
· 网络请求的优先级处理
· 缓存
· 多级别取消请求
· 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求)
劣势:
针对大文件的网络请求volley的处理还有欠缺
使用方式:
1.将对应的jar包导入
2.
RequestQueue queue;
* RequestQueue是一个请求队列对象,它可以缓存所有的HTTP请求,然后 * 按照一定的算法并发地发出这些请求。RequestQueue内部的设计就是非 * 常合适高并发的,因此我们不必为每一次HTTP请求都创建 * 一个RequestQueue对象,这 *是非常浪费资源的, * 基本上在每一个需要和网络交互的Activity中 * 创建一个RequestQueue对象就足够了。2-1 简单的网络请求getStringRequest stringRequest = new StringRequest("https://www.baidu.com/", new Response.Listener<String>() { @Override public void onResponse(String response) { show.setText("普通请求:抓取的数据是百度网页\n"+response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("TAG", error.getMessage(), error); } }); queue.add(stringRequest);queue.start(stringRequest);
2-2 post请求:Jason数据请求String url = "http://210.44.176.116/cjcx/xhcx_list.php"; StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() { @Override public void onResponse(String s) { Log.i("aa", "post请求成功" + s); show.setText("Post请求数据:\n"+s); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Log.i("aa", "post请求失败" + volleyError.toString()); Toast.makeText(ActionOne.this, volleyError.toString(), Toast.LENGTH_LONG).show(); } }) { @Override protected Map<String, String> getParams() throws AuthFailureError { HashMap<String, String> map = new HashMap<>(); map.put("post_xingming",name.getText().toString()); return map; } }; request.setTag("volleypost"); queue.add(request);ndViewById(R.id.r_j).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { JsonObjectRequest json = new JsonObjectRequest("http://op.juhe.cn/onebox/weather/query?cityname=%E6%B8%A9%E5%B7%9E&key=30a86ded9adf7510ddec4ea8376e06c6", null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { Log.d("TAG",jsonObject.toString()); String str = jsonObject.toString(); show.setText("json数据请求:\n"+str); Log.d("TAG","success"); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Log.d("TAG","error"); Toast.makeText(ActionOne.this, volleyError.toString(), Toast.LENGTH_LONG).show(); } }); queue.add(json);图片请求:ImageRequest imageRequest = new ImageRequest("http://pic.58pic.com/58pic/13/20/61/89B58PIC5Nz_1024.jpg", new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { img.setImageBitmap(bitmap); } },300, 200, Bitmap.Config.ARGB_8888, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError arg0) { // TODO Auto-generated method stub Log.d("TAG","error"); Toast.makeText(ActionOne.this, arg0.toString(), Toast.LENGTH_LONG).show(); } }); queue.add(imageRequest);使用NetworkImageView
Volley提供了一个新的控件NetworkImageView来代替传统的ImageView,这个控件的图片属性可以通过
1. mImageView.setImageUrl(url, imageLoader)
来设定。而且,这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题。
示例代码如下:1. mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
2. ... ...
3.
4. if(holder.imageRequest != null) {
5. holder.imageRequest.cancel();
6. }
7. holder.imageRequest = mImageLoader.get(BASE_UR + item.image_url, holder.imageView, R.drawable.loading, R.drawable.error);
注意,这里使用的不是ImageView控件,而是Volley新提供的com.android.volley.NetworkImageView。
另外,注意这里:
1. mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache());
ImageLoader构造函数的第二个参数是一个ImageCache的实例(严格来说,是实现ImageCache接口的某具体类的实例)
ImageCache的定义如下(在ImageLoader.java里):1. public interface ImageCache {
2. public Bitmap getBitmap(String url);
3. public void putBitmap(String url, Bitmap bitmap);
4. }
下面的网址一个lru的cache实现例子,请参考:
使用自己定制的request
我们也可以通过继承Request根据自己的需求来定制自己的request
1. protected Response parseNetworkResponse(NetworkResponse response) {
2. try {
3. String json = new String(
4. response.data, HttpHeaderParser.parseCharset(response.headers));
5. return Response.success(
6. gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
7. } catch (UnsupportedEncodingException e) {
8. return Response.error(new ParseError(e));
9. } catch (JsonSyntaxException e) {
10. return Response.error(new ParseError(e));
11. }
12. }
这段代码节选自: https://gist.github.com/ficusk/5474673
里面使用的gson(com.google.gson.Gson)是JSON的序列化和反序列化的库,可以在JSON和java model object之间进行转换。
以下是使用自定制request的例子:
1. mRequestQueue.add( new GsonRequest(url, ListResponse.class, null,
2. new Listener() {
3. public void onResponse(ListResponse response) {
4. appendItemsToList(response.item);
5. notifyDataSetChanged();
6. }
7. }
8. }