android volley 预研
来源:互联网 发布:python readline函数 编辑:程序博客网 时间:2024/06/08 08:15
Volley简介
什么是Volley?
在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,Google I/O 2013上Volley发布。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。
Volley提供的功能
简单的讲,提供了如下主要的功能:
1、封装了的异步的request请求API;
2、一个优雅和稳健的请求队列;
3、一个可扩展的架构,它使开发人员能够实现自定义的请求和响应处理机制;
4、能够使用外部HTTP Client库;
5、缓存策略;
6、自定义的网络图像加载视图(NetworkImageView,ImageLoader等);
Volley使用
示例代码:
mQueue = Volley.newRequestQueue(getApplicationContext());
mQueue.add(new StringRequest(Method.GET, "http://www.baidu.com/",
new Listener(){
@Override
public void onResponse(String arg0) {
// TODO Auto-generated method stub
Log.e("onResponse", arg0);
}
}, new ErrorListener(){
@Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
Log.e("onErrorResponse", arg0.toString());
}
}));
//mQueue.start(); 此处不需要,因为newRequest的时候自动调了这个start
首先,通过Volley的静态方法new一个请求队列,调用请求队列(RequestQueue是由缓存和网络线程构造的)的start方法。
然后,得到一个RequestQueue请求队列时,就添加一个请求Request,Volley提供有三种请求的封装,一个是StringRequest,一个事ImageRequest,还有一个是JsonRequest。
最后,add即执行。
RequestQueue的成员方法主要有下面几个:
1.public void start();//请求队列开始进行调度发vgm
2.public void stop();//队列退出调度
3.public Request add(Request request);//添加一个请求,通过调用start()来执行
4.void finish(Request request);//这个方法应该是释放请求资源的方法
5.public void cancelAll();//取消当前的请求
以下是Volley的异常列表:
AuthFailureError:如果在做一个HTTP的身份验证,可能会发生这个错误。
NetworkError:Socket关闭,服务器宕机,DNS错误都会产生这个错误。
NoConnectionError:和NetworkError类似,这个是客户端没有网络连接。
ParseError:在使用JsonObjectRequest或JsonArrayRequest时,如果接收到的JSON是畸形,会产生异常。
SERVERERROR:服务器的响应的一个错误,最有可能的4xx或5xx HTTP状态代码。
TimeoutError:Socket超时,服务器太忙或网络延迟会产生这个异常。默认情况下,Volley的超时时间为2.5秒。如果得到这个错误可以使用RetryPolicy。
Volley分析
public class Volley:
四个静态newRequestQueue接口。
public static RequestQueue newRequestQueue(Context context, HttpStack stack, int maxDiskCacheBytes);
核心代码:
可以看到。在2.3之前用的是http client,之后用的httpurlconnection
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
Network network = new BasicNetwork(stack);
RequestQueue queue;
if (maxDiskCacheBytes <= -1){
queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
}else{
queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);
}
queue.start();
return queue;
解释:
创建一个stack = new HurlStack();负责封装,发送,接收。
Network network = new BasicNetwork(stack); 负责在线程里执行。比httpstack不同在于,加入缓存头,调用httpstack,结果返回状态处理。302 401等
queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
queue.start();
public class HurlStack implements HttpStack:
负责协议的拼装,发送,接收。
关键函数:
1.public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
2.private static HttpEntity entityFromConnection(HttpURLConnection connection):组装返回用:HttpResponse.setEntity()
3.protected HttpURLConnection createConnection(URL url)
4.private HttpURLConnection openConnection(URL url, Request<?> request):打开链接,设置超时等,并确定是否https。
5.static void setConnectionParametersForRequest(HttpURLConnection connection, Request<?> request):设置参数
6.private static void addBodyIfExists(HttpURLConnection connection, Request<?> request):POST,PUT,PATCH方式的内容拼装。
public class BasicNetwork implements Network:
负责在线程里执行。比httpstack不同在于,加入缓存头,调用httpstack,结果返回状态处理。302 401等
关键函数:
public NetworkResponse performRequest(Request<?> request) throws VolleyError:唯一执行接口。返回:NetworkResponse
Map<String, String> headers = new HashMap<String, String>();
addCacheHeaders(headers, request.getCacheEntry());
httpResponse = mHttpStack.performRequest(request, headers);
StatusLine statusLine = httpResponse.getStatusLine();
int statusCode = statusLine.getStatusCode();
//错误处理,有针对401.403这里不太符合我们的需求,但不影响。
return new NetworkResponse(statusCode, responseContents, responseHeaders, false, SystemClock.elapsedRealtime() - requestStart);
返回内容。
private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry):添加缓存入口。写到头用。
public class NetworkResponse:
BasicNetwork解析后的结果
this.statusCode = statusCode;
this.data = data;
this.headers = headers;
this.notModified = notModified;
this.networkTimeMs = networkTimeMs;
public class RequestQueue:
管理队列
private final Map<String, Queue<Request<?>>> mWaitingRequests:在add时增加或修改。在finish时:remove
private final Set<Request<?>> mCurrentRequests:add,cancelAll,finish。
构建分发器的部件:
private final PriorityBlockingQueue<Request<?>> mCacheQueue
private final PriorityBlockingQueue<Request<?>> mNetworkQue:不缓存增加
private final Cache mCache;缓存。
private final Network mNetwork;
private final ResponseDelivery mDelivery
;
两个分发器:
private NetworkDispatcher[] mDispatchers;相当于线程池,可制定,默认4
private CacheDispatcher mCacheDispatcher;缓存分发器
new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery);
一个自增计数器
private AtomicInteger mSequenceGenerator。request.setSequence(getSequenceNumber());
说明:之所以没有用线程池等,完全是因为PriorityBlockingQueue所致!所以看到代码不是特别爽。建议大家看一下:java.util.concurrent包。
public abstract class Request<T> implements Comparable<Request<T>>
请求基类。一切皆源于此。
public class NetworkDispatcher extends Thread
网络下载部分
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
request = mQueue.take();
NetworkResponse networkResponse = mNetwork.performRequest(request);
Response<?> response = request.parseNetworkResponse(networkResponse);
mDelivery.postResponse(request, response);
}
}
public class AndroidAuthenticator implements Authenticator
用户token管理
public class ImageRequest extends Request<Bitmap>
一个实例化的图片请求
public class ImageLoader
图片加载和缓存.很简洁的一个使用
public class NetworkImageView extends ImageView
图片加载视图,调用ImageLoader加载图片
关于cookie,编码格式,参数设置等::
StringRequest request= new StringRequest(Method.POST, url,
this, this) {
@Override
protected Response<String> parseNetworkResponse(
NetworkResponse response) {
// TODO Auto-generated method stub
try {
Map<String, String> responseHeaders = response.headers;
String rawCookies = responseHeaders.get("Set-Cookie");
String dataString = new String(response.data, "UTF-8");
return Response.success(dataString,HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap localHashMap = new HashMap();
localHashMap.put("Cookie", "你的cookie值");
return localHashMap;
}
//设置post参数
protected Map<String, String> getParams() {
if(params==null){
return new HashMap<String, String>();
}
return params;
}
//设置编码格式
@Override
protected Response<String> parseNetworkResponse(
NetworkResponse response) {
// TODO Auto-generated method stub
try {
String dataString = new String(response.data, "UTF-8");
return Response.success(dataString,HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
};
后记:
1.不适合大数据传输。所以对于大数据需要自己写请求,比如往上发图片,下载安装包,大文件等。其实对于单独安装包,大文件,android是有提供工具的,2.3引入了DownloadManager可以处理复杂的文件下载,
2.对于Requestqueue,建议部分考虑全局单例。 因为线程开启关闭是要浪费资源的。默认是开5线程(一个缓存,四个网络请求)。
3.缓存会导致newRequestQueue创建非常的慢,有人说达到十几秒。解决方案:有人在stackoverflow中提到过这个问题,然后他给出了解决方案。在initialize中,给FileOutputStream在套一层BufferedOutputStream。本人测试过,速度有十倍的提升。基本能控制初始化的时间在1-3s。另一个方案是全局一个requestqueue.
- android volley 预研
- Android-Volley
- Android volley
- android volley
- android volley
- Android-volley
- Android Volley - volley StringRequest編碼問題
- Android Volley - volley StringRequest編碼問題
- Android Volley,使用Volley加载网络图片
- Volley学习(一)Android Volley源码解析
- Android Volley使用之一:Volley基础用法
- Android Volley 使用Volley加载网络图片
- android-Volley框架简介
- android的volley框架
- Android,Volley使用介绍
- Android Volley分析
- Android 解读Volley
- Android Volley框架使用
- Android View的onTouchEvent和OnTouch区别
- Robotium之Android控件定位实践和建议(Appium/UIAutomator姊妹篇)
- 计蒜客 京东的物流路径
- Spring事务 UnexpectedRollbackException
- SCOM Schema 2.0转为1.0
- android volley 预研
- 2015 Multi-University Training Contest 3 RGCDQ
- 新手小问题总结
- Robotium Solo Api 简介
- select * into outfile导出到excel乱码
- 五款常用mysql slow log分析工具的比较分析
- listview中显示不同的视图布局
- hibernate持久化对象状态
- 启用SVN的分支管理