您的位置:首页 > 理论基础 > 计算机网络

使用Velloy执行网络数据传输

2016-03-02 09:09 288 查看
此文为摘抄胡凯翻译的安卓官方文档。
一、Volley简介:
Volley是一个HTTP库,它能够帮助Androidapp更方便地执行网络操作,最重要的是,它更快速高效。

Volley的优点:

自动调度网络请求。
高并发网络连接。
通过标准的HTTPcachecoherence(高速缓存一致性)缓存磁盘和内存透明的响应。
支持指定请求的优先级。
撤销请求API。我们可以取消单个请求,或者指定取消请求队列中的一个区域。
框架容易被定制,例如,定制重试或者回退功能。
强大的指令(Strongordering)可以使得异步加载网络数据并正确地显示到UI的操作更加简单。
包含了调试与追踪工具。

Volley的缺点:Volley不适合用来下载大的数据文件。因为Volley会保持在解析的过程中所有的响应。
二、发送简单的网络请求
step0:添加网络访问权限:android.permission.INTERNET,只有添加了权限才能进行网络访问相关的操作;
step1:创建一个请求队列:RequestQueue对象,
step2:创建一个请求:Request对象(使用StringRequest加载字符串,使用ImageRequest加载图片)
step3:把请求添加到请求队列中,mRequestQueue.add(mRequest),也就将请求发送出去了;
管理用来执行网络操作的工作线程,从缓存中读取数据,写数据到缓存,并解析Http的相应内容。请求解析原始的响应数据,Volley会把解析完的响应数据分发给主线程。
下面为一个简单的demo:

//创建一个请求队列
RequestQueuequeue=Volley.newRequestQueue(this);
Stringurl="http://www.baidu.com";
//创建一个请求任务StringRequest,
//有4个参数,分别表示请求类型(GET或POST等)、URL(String类型)、响应监听者、错误监听者(参数可以为null)
StringRequeststringRequest=newStringRequest(Request.Method.GET,url,
newResponse.Listener(){
@Override
publicvoidonResponse(Stringresponse){
//response为响应得到的字符串
//在此处对得到的响应内容进行进一步使用
}
},newResponse.ErrorListener(){
@Override
publicvoidonErrorResponse(VolleyErrorerror){
//响应失败进行的一些操作
}
});
//把请求任务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的请求任务所卡到。

publicstaticfinalStringTAG="MyTag";
StringRequeststringRequest;//假定这个对象已存在
RequestQueuemRequestQueue;//
假定这个对象已存在
//给请求设置标签tag
stringRequest.setTag(TAG);
//把请求添加到请求队列中
mRequestQueue.add(stringRequest);
...........................
//在activity的onStop()方法里面,取消所有的包含这个tag的请求任务。
@Override
protectedvoidonStop(){
super.onStop();
if(mRequestQueue!=null){
mRequestQueue.cancelAll(TAG);
}
}


三、建立自己的请求队列

一个
RequestQueue
需要两部分来支持它的工作:一部分是网络操作,用来传输请求,另外一个是用来处理缓存操作的
Cache。在Volley的工具箱中包含了标准的实现方式:
DiskBasedCache
提供了每个文件与对应响应数据一一映射的缓存实现。
BasicNetwork
提供了一个基于AndroidHttpClient或者HttpURLConnection的网络传输(通过版本判断使用哪种网络访问方式)。
自定义RequestQueue的demo:

		Cachecache=newDiskBasedCache(getCacheDir(),1024*1024);
		Networknetwork=newBasicNetwork(newHurlStack());
		RequestQueuemRequestQueue=newRequestQueue(cache,network);
mRequestQueue.start();


使用单例模式(两种方式)
1.static的单例:里面封装了
RequestQueue
对象与其它的
Volley功能。官方推荐
2.application的单例:继承Application类并在onCreate()方法中创建RequestQueue对象。官方不推荐。
关键概念:
RequestQueue
必须使用Applicationcontext来实例化,而不是Activitycontext。这确保了
RequestQueue
在我们
app的生命周期中一直存活,而不会因为activity的重新创建而被重新创建(例如,当用户旋转设备时)。

单例类的demo:

publicclassMySingleton{
privatestaticMySingletonmInstance;
privateRequestQueuemRequestQueue;
privateImageLoadermImageLoader;
privatestaticContextmCtx;
privateMySingleton(Contextcontext){
mCtx=context;
mRequestQueue=getRequestQueue();
mImageLoader=newImageLoader(mRequestQueue,
newImageLoader.ImageCache(){
privatefinalLruCache<String,Bitmap>
cache=newLruCache<String,Bitmap>(20);
@Override
publicBitmapgetBitmap(Stringurl){
returncache.get(url);
}
@Override
publicvoidputBitmap(Stringurl,Bitmapbitmap){
cache.put(url,bitmap);
}
});
}
publicstaticsynchronizedMySingletongetInstance(Contextcontext){
if(mInstance==null){
mInstance=newMySingleton(context);
}
returnmInstance;
}
publicRequestQueuegetRequestQueue(){
if(mRequestQueue==null){
//getApplicationContext()iskey,itkeepsyoufromleakingthe
//ActivityorBroadcastReceiverifsomeonepassesonein.
mRequestQueue=Volley.newRequestQueue(mCtx.getApplicationContext());
}
returnmRequestQueue;
}
public<T>voidaddToRequestQueue(Request<T>req){
getRequestQueue().add(req);
}
publicImageLoadergetImageLoader(){
returnmImageLoader;
}
}


RequestQueue的使用

//获得请求队列(单例RequestQueue)
RequestQueuequeue=MySingleton.getInstance(this.getApplicationContext()).
getRequestQueue();
...
//将请求添加到请求队列中
MySingleton.getInstance(this).addToRequestQueue(stringRequest);


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

网络加载一张图片:
1.使用ImageRequest,返回bitmap;

ImageViewmImageView;
Stringurl="http://i.imgur.com/7spzG.png";
mImageView=(ImageView)findViewById(R.id.myImage);
...
//通过url请求图片并在ImageView上显示
ImageRequestrequest=newImageRequest(url,
newResponse.Listener(){
@Override
publicvoidonResponse(Bitmapbitmap){
mImageView.setImageBitmap(bitmap);
}
},0,0,null,
newResponse.ErrorListener(){
publicvoidonErrorResponse(VolleyErrorerror){
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"/>


ImageLoadermImageLoader;
ImageViewmImageView;
//TheURLfortheimagethatisbeingloaded.
privatestaticfinalStringIMAGE_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));


ImageLoadermImageLoader;
NetworkImageViewmNetworkImageView;
privatestaticfinalStringIMAGE_URL=
"http://developer.android.com/images/training/system-ui.png";
...
//GettheNetworkImageViewthatwilldisplaytheimage.
mNetworkImageView=(NetworkImageView)findViewById(R.id.networkImageView);
//GettheImageLoaderthroughyoursingletonclass.
mImageLoader=MySingleton.getInstance(this).getImageLoader();
//SettheURLoftheimagethatshouldbeloadedintothisview,and
//specifytheImageLoaderthatwillbeusedtomaketherequest.
mNetworkImageView.setImageUrl(IMAGE_URL,mImageLoader);


上面的代码是通过通过前一节课讲到的单例类来访问
RequestQueue
ImageLoader
。这种方法保证了我们的
app创建这些类的单例会持续存在于app的生命周期。这对于
ImageLoader
(一个用来处理加载与缓存图片的帮助类)很重要的原因是:内存缓存的主要功能是允许非抖动旋转。使用单例模式可以使得
bitmap的缓存比activity存在的时间长。如果我们在activity中创建
ImageLoader
,这个
ImageLoader
有可能会在每次旋转设备的时候都被重新创建。这可能会导致抖动。

4.JsonObjectRequest与JsonArrayRequest

TextViewmTxtDisplay;
ImageViewmImageView;
mTxtDisplay=(TextView)findViewById(R.id.txtDisplay);
Stringurl="http://my-json-feed";
JsonObjectRequestjsObjRequest=newJsonObjectRequest
(Request.Method.GET,url,null,newResponse.Listener(){
@Override
publicvoidonResponse(JSONObjectresponse){
mTxtDisplay.setText("Response:"+response.toString());
}
},newResponse.ErrorListener(){
@Override
publicvoidonErrorResponse(VolleyErrorerror){
//TODOAuto-generatedmethodstub
}
});
//AccesstheRequestQueuethroughyoursingletonclass.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: