使用Velloy执行网络数据传输

此文为摘抄胡凯翻译的安卓官方文档。
一、Volley简介:
  Volley是一个HTTP库,它能够帮助Android app更方便地执行网络操作,最重要的是,它更快速高效。
Volley的优点:
  • 自动调度网络请求。
  • 高并发网络连接。
  • 通过标准的 HTTP cache coherence(高速缓存一致性)缓存磁盘和内存透明的响应。
  • 支持指定请求的优先级。
  • 撤销请求 API。我们可以取消单个请求,或者指定取消请求队列中的一个区域。
  • 框架容易被定制,例如,定制重试或者回退功能。
  • 强大的指令(Strong ordering)可以使得异步加载网络数据并正确地显示到 UI 的操作更加简单。
  • 包含了调试与追踪工具。
Volley的缺点:Volley 不适合用来下载大的数据文件。因为 Volley 会保持在解析的过程中所有的响应。
二、发送简单的网络请求
step0:添加网络访问权限:android.permission.INTERNET,只有添加了权限才能进行网络访问相关的操作;
step1:创建一个请求队列:RequestQueue对象,
step2:创建一个请求:Request对象(使用StringRequest加载字符串,使用ImageRequest加载图片)
step3:把请求添加到请求队列中,mRequestQueue.add(mRequest),也就将请求发送出去了;
管理用来执行网络操作的工作线程,从缓存中读取数据,写数据到缓存,并解析Http的相应内容。请求解析原始的响应数据,Volley会把解析完的响应数据分发给主线程。
下面为一个简单的demo:
   
   
// 创建一个请求队列
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.baidu.com";
 
// 创建一个请求任务StringRequest,
//有4个参数,分别表示请求类型(GET或POST等)、URL(String类型)、响应监听者、错误监听者(参数可以为null)
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener() {
@Override
public void onResponse(String response) {
// response为响应得到的字符串
// 在此处对得到的响应内容进行进一步使用
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// 响应失败进行的一些操作
}
});
// 把请求任务stringRequest添加到请求队列queue中
queue.add(stringRequest);

注意:那些比较耗时的操作,例如I/O与解析parsing/decoding都是执行在工作线程。
                    你可以在任何线程中添加一个请求,但是响应结果都是返回到主线程的。
step4:如何取消请求任务:调用Request对象的cancel()方法。
当需要有选择的取消一些请求时,可以采用以下方法:为每一个请求对象都绑定一个tag对象,然后使用这个tag来提供取消的范围。
例1:将所有请求都绑定到执行的activity上,然后可以在onstop()方法中执行requestQueue.cancelAll(this)。
例2:为ViewPager中的所有请求缩略图Request对象分别打上对应Tab的tag。并在滑动时取消这些请求,用来确保新生成的tab不会被前面tab的请求任务所卡到。
   
   
public static final String TAG = "MyTag";
StringRequest stringRequest; // 假定这个对象已存在
RequestQueue mRequestQueue; // 假定这个对象已存在
// 给请求设置标签tag
stringRequest.setTag(TAG);
// 把请求添加到请求队列中
mRequestQueue.add(stringRequest);
...........................  
//activityonStop()方法里面,取消所有的包含这个tag的请求任务。
@Override
protected void onStop () {
super.onStop();
if (mRequestQueue != null) {
mRequestQueue.cancelAll(TAG);
}
}

三、建立自己的请求队列
               一个  RequestQueue  需要两部分来支持它的工作:一部分是网络操作,用来传输请求,另外一个是用来处理缓存操作的 Cache。在 Volley 的工具箱中包含了标准的实现方式: DiskBasedCache  提供了每个文件与对应响应数据一一映射的缓存实现。 BasicNetwork  提供了一个基于  AndroidHttpClient  或者  HttpURLConnection  的网络传输(通过版本判断使用哪种网络访问方式)。
自定义RequestQueue的demo:
   
   
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024);
Network network = new BasicNetwork(new HurlStack());
RequestQueue mRequestQueue = new RequestQueue(cache, network);
mRequestQueue.start();
使用单例模式(两种方式)
1.static的单例: 里面封装了 RequestQueue  对象与其它的 Volley 功能。官方推荐
2.application的单例:继承Application类并在onCreate()方法中创建RequestQueue对象。官方不推荐。
关键概念: RequestQueue必须使用 Application context 来实例化,而不是 Activity context。这确保了   RequestQueue  在我们 app 的生命周期中一直存活,而不会因为 activity 的重新创建而被重新创建(例如,当用户旋转设备时)。
单例类的demo:
    
    
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private ImageLoader mImageLoader;
private static Context mCtx;
 
private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
 
mImageLoader = new ImageLoader(mRequestQueue,
new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap>
cache = new LruCache<String, Bitmap>(20);
 
@Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
 
@Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url, bitmap);
}
});
}
 
public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}
 
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
 
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
 
public ImageLoader getImageLoader() {
return mImageLoader;
}
}
RequestQueue的使用
    
    
// 获得请求队列(单例RequestQueue)
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
getRequestQueue();
...
 
// 将请求添加到请求队列中
MySingleton.getInstance(this).addToRequestQueue(stringRequest);

四、常用的网络请求
Volley支持的常用请求:
StringRequest:指定一个URL并在响应回调中接收一个原始的字符串数据;
ImageRequest:指定一个URL并在响应回调中接收一个图片;
JsonObjectRequest与JsonArrayRequest(均为JsonRequest的子类):指定一个URL并在响应回调中获取一个JSON对象或者JSON数组。

网络加载一张图片:
1.使用ImageRequest,返回bitmap;
    
    
ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
...
 
// 通过url请求图片并在ImageView上显示
ImageRequest request = new ImageRequest(url,
new Response.Listener() {
@Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
mImageView.setImageResource(R.drawable.image_load_error);
}
});
// 通过单例类访问RequestQueue
MySingleton.getInstance(this).addToRequestQueue(request);
2.ImageLoader:处理加载和缓存从网络获取到的图片的帮助类,是大量ImageRequest的协调器,在大量加载图片时可防止图片抖动。
3.NetworkImageView:在ImageLoader基础上建立,有效替换ImageView。
    
    
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/networkImageView"
android:layout_width="150dp"
android:layout_height="170dp"
android:layout_centerHorizontal="true" />
     
     
ImageLoader mImageLoader;
ImageView mImageView;
// The URL for the image that is being loaded.
private static final String IMAGE_URL =
"http://developer.android.com/images/training/system-ui.png";
...
mImageView = (ImageView) findViewById(R.id.regularImageView);
 
// 通过单例类获得ImageLoader对象
mImageLoader = MySingleton.getInstance(this).getImageLoader();
mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
R.drawable.def_image, R.drawable.err_image));
      
      
ImageLoader mImageLoader;
NetworkImageView mNetworkImageView;
private static final String IMAGE_URL =
"http://developer.android.com/images/training/system-ui.png";
...
 
// Get the NetworkImageView that will display the image.
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
 
// Get the ImageLoader through your singleton class.
mImageLoader = MySingleton.getInstance(this).getImageLoader();
 
// Set the URL of the image that should be loaded into this view, and
// specify the ImageLoader that will be used to make the request.
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
上面的代码是通过通过前一节课讲到的单例类来访问  RequestQueue  与  ImageLoader 。这种方法保证了我们的 app 创建这些类的单例会持续存在于 app 的生命周期。这对于  ImageLoader (一个用来处理加载与缓存图片的帮助类)很重要的原因是:内存缓存的主要功能是允许非抖动旋转。使用单例模式可以使得 bitmap 的缓存比 activity 存在的时间长。如果我们在 activity 中创建  ImageLoader ,这个  ImageLoader  有可能会在每次旋转设备的时候都被重新创建。这可能会导致抖动。
4.JsonObjectRequest与JsonArrayRequest
    
    
TextView mTxtDisplay;
ImageView mImageView;
mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
String url = "http://my-json-feed";
 
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener() {
 
@Override
public void onResponse(JSONObject response) {
mTxtDisplay.setText("Response: " + response.toString());
}
}, new Response.ErrorListener() {
 
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
 
}
});
 
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值