Volley源码解读上Word文档格式.docx
- 文档编号:6785211
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:20
- 大小:55.58KB
Volley源码解读上Word文档格式.docx
《Volley源码解读上Word文档格式.docx》由会员分享,可在线阅读,更多相关《Volley源码解读上Word文档格式.docx(20页珍藏版)》请在冰点文库上搜索。
Toast.makeText(MainActivity.this,arg0.toString(),Toast.LENGTH_SHORT).show();
failed"
arg0.toString());
});
//为每一个请求设置Tag标记,便于后期对request的管理
request.setTag("
testGet"
);
//添加到请求队列中去
MyApplication.getHttpQueues().add(request)
Volley的具体使用方式可以看这篇博文《Volley框架的使用》
Volley的源码(基于Vollley1.0.11)
在上边可以看到我们通过调用Volley提供的静态方法newRequestQueue来获取到一个消息队列,其源码其实是调用了另一个newRequestQueue方法,源码中有多个不同的newRequestQueue函数
//所有的newRequestQueue函数都是调用的该函数,传入参数依次为上下文对象,http请求栈,缓存的最大值
publicstaticRequestQueuenewRequestQueue(Contextcontext,HttpStackstack,intmaxDiskCacheBytes){
//用于缓存的文件路径
FilecacheDir=newFile(context.getCacheDir(),DEFAULT_CACHE_DIR);
StringuserAgent="
volley/0"
try{
StringpackageName=context.getPackageName();
PackageInfoinfo=context.getPackageManager().getPackageInfo(packageName,0);
userAgent=packageName+"
/"
+info.versionCode;
}catch(NameNotFoundExceptione){
//传入的stack为空,也就是没有自定义stack
if(stack==null){
//根据不同的SDK版本使用不同的Stack进行存储
if(Build.VERSION.SDK_INT>
=9){
stack=newHurlStack();
}else{
stack=newHttpClientStack(AndroidHttpClient.newInstance(userAgent));
//在构造好存储队列之后,构造网络请求
Networknetwork=newBasicNetwork(stack);
//构造请求队列
RequestQueuequeue;
if(maxDiskCacheBytes<
=-1)
{
//Nomaximumsizespecified
queue=newRequestQueue(newDiskBasedCache(cacheDir),network);
else
//Diskcachesizespecified
queue=newRequestQueue(newDiskBasedCache(cacheDir,maxDiskCacheBytes),network);
//让队列开始工作
queue.start();
returnqueue;
//---下边的函数都是调用的第一个函数---
//传入两个参数
publicstaticRequestQueuenewRequestQueue(Contextcontext,intmaxDiskCacheBytes){
returnnewRequestQueue(context,null,maxDiskCacheBytes);
}
publicstaticRequestQueuenewRequestQueue(Contextcontext,HttpStackstack)
returnnewRequestQueue(context,stack,-1);
//只有一个传入参数
publicstaticRequestQueuenewRequestQueue(Contextcontext){
returnnewRequestQueue(context,null);
//
由此可以梳理一下调用newRequest()方法之后所发生的的操作。
首先生成了文件的缓存路径
然后判断是否自定义了stack队列,若没有定义队列,则根据SDK版本生成默认的stack,SDK大于9使用HurlStack,否则使用HttpClientStack
声明网络请求的实例
根据传入的maxDiskCacheBytes来构造请求队列
可以看到其工作流程很清晰,其中主要分为stack的创建,network的创建,和requestqueue的创建。
stack创建
//传入的stack为空,也就是没有自定义stack,创建默认的stack
默认的stack根据SDK版本的不同分为HurlStack和HttpClientStack,两者其实都是HttpStack的实现类,主要区别在于适用的SDK版本不一样,HurlStack更加适用于Android版本在2.3和更高版本,因为其内部实现是用了HttpURLConnection这个类。
而HttpClientStack适用于Android版本在2.2和更低版本(现在市面上已经没有了)。
首先来看一下低版本中使用的HttpClientStack的实现:
HttpClientStack
publicHttpResponseperformRequest(Request<
?
>
request,Map<
String,String>
additionalHeaders)
throwsIOException,AuthFailureError{
//首先是创建http的request
HttpUriRequesthttpRequest=createHttpRequest(request,additionalHeaders);
addHeaders(httpRequest,additionalHeaders);
addHeaders(httpRequest,request.getHeaders());
onPrepareRequest(httpRequest);
//获取到request请求中的参数
HttpParamshttpParams=httpRequest.getParams();
inttimeoutMs=request.getTimeoutMs();
//TODO:
Reevaluatethisconnectiontimeoutbasedonmorewide-scale
//datacollectionandpossiblydifferentforwifivs.3G.
//请求超时机制
HttpConnectionParams.setConnectionTimeout(httpParams,5000);
HttpConnectionParams.setSoTimeout(httpParams,timeoutMs);
//将Request提交给HttpClient去执行,并将执行结果返回
returnmClient.execute(httpRequest);
在这里边主要有三个动作:
创建HttpRequest
封装参数
将HttpRequest提交给HttpClient去执行(在外部是传入了一个AndroidHttpClient的实例)
其实HurlStack所做的操作和HttpClientStack类似,只是在最后执行网络请求的时候HurlStack使用的是HttpURLConnection,而HttpClientStack使用HttpClient来执行任务。
接下来看一下HurlStack的具体实现:
HurlStack:
以下是HurlStack中的核心方法performRequest,实现了HttpStack接口定义的方法
//根据请求来获取url地址
Stringurl=request.getUrl();
//保存请求头
HashMap<
map=newHashMap<
();
map.putAll(request.getHeaders());
map.putAll(additionalHeaders);
//如果有需要可以通过UrlRewriter接口重写url地址
if(mUrlRewriter!
=null){
Stringrewritten=mUrlRewriter.rewriteUrl(url);
if(rewritten==null){
thrownewIOException("
URLblockedbyrewriter:
"
+url);
url=rewritten;
//生成最终使用的url
URLparsedUrl=newURL(url);
//开启连接
HttpURLConnectionconnection=openConnection(parsedUrl,request);
//吧request中请求头的信息添加进去
for(StringheaderName:
map.keySet()){
connection.addRequestProperty(headerName,map.get(headerName));
//设置请求的参数
setConnectionParametersForRequest(connection,request);
//InitializeHttpResponsewithdatafromtheHttpURLConnection.
ProtocolVersionprotocolVersion=newProtocolVersion("
HTTP"
1,1);
intresponseCode=connection.getResponseCode();
if(responseCode==-1){
//-1isreturnedbygetResponseCode()iftheresponsecodecouldnotberetrieved.
//Signaltothecallerthatsomethingwaswrongwiththeconnection.
CouldnotretrieveresponsecodefromHttpUrlConnection."
StatusLineresponseStatus=newBasicStatusLine(protocolVersion,
connection.getResponseCode(),connection.getResponseMessage());
//封装请求的结果
BasicHttpResponseresponse=newBasicHttpResponse(responseStatus);
//从connecttion中取出实体并保存在response中
response.setEntity(entityFromConnection(connection));
for(Entry<
String,List<
header:
connection.getHeaderFields().entrySet()){
if(header.getKey()!
Headerh=newBasicHeader(header.getKey(),header.getValue().get(0));
response.addHeader(h);
//返回响应response
returnresponse;
以上这两种方式就是Volley中两种不同的请求队列的方式,在构造完stack之后就需要用构造好的stack来创建一个Netwoork实例。
构造网络请求
在下边这个方法中完成了对网络请求的发起和对返回的response的校验封装,最终返回一个NetworkResponse实例
@Override
publicNetworkResponseperformRequest(Request<
request)throwsVolleyError{
//记录请求开始的时间
longrequestStart=SystemClock.elapsedRealtime();
while(true){
//用于接收响应报文
HttpResponsehttpResponse=null;
byte[]responseContents=null;
Map<
responseHeaders=Collections.emptyMap();
//Gatherheaders.
headers=newHashMap<
//添加缓存头,从请求中获取需要缓存的字段
addCacheHeaders(headers,request.getCacheEntry());
//调用HttpStack定义的方法来执行请求,具体使用哪种stack由当前SDK版本决定
httpResponse=mHttpStack.performRequest(request,headers);
//从之前返回的httpResponse中获取返回信息
StatusLinestatusLine=httpResponse.getStatusLine();
intstatusCode=statusLine.getStatusCode();
responseHeaders=convertHeaders(httpResponse.getAllHeaders());
//Handlecachevalidation.处理缓存的更新
if(statusCode==HttpStatus.SC_NOT_MODIFIED){
Entryentry=request.getCacheEntry();
if(entry==null){
returnnewNetworkResponse(HttpStatus.SC_NOT_MODIFIED,null,
responseHeaders,true,
SystemClock.elapsedRealtime()-requestStart);
//AHTTP304responsedoesnothaveallheaderfields.We
//havetousetheheaderfieldsfromthecacheentryplus
//thenewonesfromtheresponse.
//http:
//www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
entry.responseHeaders.putAll(responseHeaders);
returnnewNetworkResponse(HttpStatus.SC_NOT_MODIFIED,entry.data,
entry.responseHeaders,true,
//Handlemovedresources重定向url进行请求
if(statusCode==HttpStatus.SC_MOVED_PERMANENTLY||statusCode==HttpStatus.SC_MOVED_TEMPORARILY){
StringnewUrl=responseHeaders.get("
Location"
request.setRedirectUrl(newUrl);
//Someresponsessuchas204sdonothavecontent.Wemustcheck.
//检查返回的response是否有内容,有的话取出保存,没有的话用byte数组填充。
if(httpResponse.getEntity()!
responseContents=entityToBytes(httpResponse.getEntity());
//Add0byteresponseasawayofhonestlyrepresentinga
//no-contentrequest.
responseContents=newbyte[0];
//iftherequestisslow,logit.,计算请求周期时间
longrequestLifetime=SystemClock.elapsedRealtime()-requestStart;
//用llog输出这是一次缓慢的网络请求
logSlowRequests(requestLifetime,request,responseContents,statusLine);
//如果返回的状态码小于200或者是大于299,报出异常
if(statusCode<
200||statusCode>
299){
thrownewIOException();
returnnewNetworkResponse(statusCode,responseContents,responseHeaders,false,
//下边就是异常的处理
}catch(SocketTimeoutExceptione){
attemptRetryOnException("
socket"
request,newTimeoutError());
}catch(ConnectTimeoutExceptione){
connection"
}catch(MalformedURLExceptione){
thrownewRuntimeException("
BadURL"
+request.getUrl(),e);
}catch(IOExceptione){
intstatusCode=0;
NetworkResponsenetworkResponse=null;
if(httpResponse!
statusCode=httpResponse.getStatusLine().getStatusCode();
thrownewNoConnectionError(e);
if(statusCode==HttpStatus.SC_MOVED_PERMANENTLY||
statusCode==HttpStatu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Volley 源码 解读