最近用到xutil框架,對httputil源碼閱讀下。
httputils一些成員變量:
//存放http訪問資源緩存的是個map,key是url;裏面有默認緩存大小和緩存時間。
public final static HttpCache sHttpCache = new HttpCache();
//它使用httpclient並沒有採用urlconnection
private final DefaultHttpClient httpClient;urlconnection
//當網絡返回301,302的時候保存參數再次訪問
private HttpRedirectHandler httpRedirectHandler;
接下來是httputils一些初始化的構造方法,裏面設置了connTimeout、userAgentdeng,以及做了http和https不同的訪問。
//設置了請求和結果的攔截器,使用gzip
httpClient.addRequestInterceptor
httpClient.addResponseInterceptor
接下來就是send了,今天說些不帶文件的訪問。
private <T> HttpHandler<T> sendRequest(HttpRequest request, RequestParams params, RequestCallBack<T> callBack) {
HttpHandler<T> handler = new HttpHandler<T>(httpClient, httpContext, responseTextCharset, callBack);
handler.setExpiry(currentRequestExpiry);
handler.setHttpRedirectHandler(httpRedirectHandler);
request.setRequestParams(params, handler);
if (params != null) {
handler.setPriority(params.getPriority());
}
handler.executeOnExecutor(EXECUTOR, request);
return handler;
}
new httphandler對象,裏面傳入了一個requestcallback回調,request不說了。進入httphandler裏面看看;
它的父類是PriorityAsyncTask,httphandler在初始化的時候做了哪些操作?進入父類看看。
public PriorityAsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
LogUtils.d(e.getMessage());
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
//聲明mfuture;和mworker關聯結果類型是result
mFuture = new FutureTask(mWorker);
//postresult裏面是發了message通知完成,doinbackground調用子類的方法。進入httphandler。
return postResult(doInBackground(mParams));
在httphandler的doinbackground方法裏面:
@Override
protected Void doInBackground(Object... params) {
if (this.state == State.CANCELLED || params == null || params.length == 0) return null;
if (params.length > 3) {
fileSavePath = String.valueOf(params[1]);
isDownloadingFile = fileSavePath != null;
autoResume = (Boolean) params[2];
autoRename = (Boolean) params[3];
}
try {
if (this.state == State.CANCELLED) return null;
// init request & requestUrl
request = (HttpRequestBase) params[0];
requestUrl = request.getURI().toString();
if (callback != null) {
callback.setRequestUrl(requestUrl);
}
this.publishProgress(UPDATE_START);
lastUpdateTime = SystemClock.uptimeMillis();
ResponseInfo<T> responseInfo = sendRequest(request);
if (responseInfo != null) {
this.publishProgress(UPDATE_SUCCESS, responseInfo);
return null;
}
} catch (HttpException e) {
this.publishProgress(UPDATE_FAILURE, e, e.getMessage());
}
return null;
}
callback回調信息。
ResponseInfo responseInfo = sendRequest(request);
在方法sendrequest裏面進行的網絡訪問,如果存在httpcache的key的話就直接返回結果,反之執行網絡訪問。根據返回碼來做不同的判斷,比如再次請求或者拋出異常,這裏面都會有一個iscancal方法,相信大家看了源碼都會發現有什麼作用的。
所有的操作中,如果拋出異常的話,整理異常信息,然後往上層拋,最後拋出httpexception總異常,是一個異常處理框架。
然後可以看到從httputil.send方法中,httphandler調用了
handler.executeOnExecutor(EXECUTOR, request);
將線程池傳入。對於mworker和mFuture筆者不是很瞭解,就不解釋。
如果解釋有誤請提出,我會改正,共同學習。這篇只是講解了一部分。