一、new HttpClient()
构造函数
1、三种构造显示的构造方式:
public HttpUtils(int connTimeout, String userAgent)
定义请求的connectionTimeout和客户端使用的代理设置。
HttpUtils(String userAgent)
HttpUtils(int connTimeout)
2、使用apache的DefaultHttpClient进行实现,在构造函数中进行预设值。
1、使用connTimeout进行超时的设定
2、代理的设定,如果是null的话,先使用android默认使用的代理,通过反射进行得到:
sysResCls = Class.forName("com.android.internal.R$string"); Field webUserAgentField = sysResCls.getDeclaredField("web_user_agent"); Integer resId = (Integer) webUserAgentField.get(null); webUserAgent = this.getString(resId);
以上得到(2015-06-08打印)
Mozilla/5.0 (Linux; U; Android %s) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 %sSafari/534.30
否则,使用自己设置的默认的代理服务器(这个最好还是要和上面的保持最新):
Mozilla/5.0 (Linux; U; Android %s) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 %sSafari/533.1
3、进行了HttpUtils的构造之后,用户能够进行自定义的某些功能的配置。
二、send(并行方式进行request请求)
1、HttpRequest请求的构造
>
1.1、
HttpRequest extends HttpRequestBase implements HttpEntityEnclosingRequest
使用apache的HttpRequestBase类,该类提供了构造HttpRequest的基本属性和方法,并实现了HttpEntityEnclosingRequest
这个接口,该接口中定义了getEntity
和setEntity
方法,方便entity的获取。
1.2、在HttpRequest
构造参数中,传入“method”和“uri”,这样,就可以构造一个httprequest了。
1.3、HttpHandler handler = new HttpHandler(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;设置一个Handler处理器,将这个request进行处理。
2、具体executeOnExecutor请求的处理
##三、sendSync(同步)执行请求。 ###1、同步请求比较简单,大概步骤就是: ####1.1、cache将运行的结果存储在LRUCache中;下次执行一个对资源URI的请求的时候,先从cache中找到结果,如果能找到,就直接返回,否则执行网络请求。 ####1.2、进行retryHandler的对象的建立,执行网络请求的时候,如果出现了一些希望重连的情况,要不断的进行重连。所以,这部分网络的请求,要使用while(true)的循环不断重连。 ####1.3、在遇到我们不希望重连的情况的时候,直接抛出异常,中断执行,跳出while循环。1、使用线程处理器Executor去执行这个task:
public final PriorityAsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params) {
if (mExecuteInvoked) {
throw new IllegalStateException("Cannot execute task:"
+ " the task is already executed.");
}
mExecuteInvoked = true;
onPreExecute();
mWorker.mParams = params;
exec.execute(new PriorityRunnable(priority, mFuture));
return this;
}
mExecutorInvoked表示是否这个task正在执行,现进行判断,执行的时候,将这个值置为true;
2、使用Callable和FutureTask的方式并行的运行线程,使用Executor进行线程的执行。
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
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);
}
}
};
}
先定义一个WorkerRunnable,传入希望运行的参数;继而定义一个Futuretask,获取到get()执行的结果,并在
private Result postResult(Result result) {中将最后结果的值使用Handler传递给MainThread。
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult(this, result));
message.sendToTarget();
return result;
}3、以上就是send(并行)方法执行的过程。
1.4、代码如下:
public ResponseStream sendRequest(HttpRequestBase request) throws HttpException { HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler(); while (true) { boolean retry = true; IOException exception = null; try { requestUrl = request.getURI().toString(); requestMethod = request.getMethod(); if (HttpUtils.sHttpCache.isEnabled(requestMethod)) { String result = HttpUtils.sHttpCache.get(requestUrl); if (result != null) { return new ResponseStream(result); } } HttpResponse response = client.execute(request, context); return handleResponse(response); } catch (UnknownHostException e) { exception = e; retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } catch (IOException e) { exception = e; retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } catch (NullPointerException e) { exception = new IOException(e.getMessage()); exception.initCause(e); retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } catch (HttpException e) { throw e; } catch (Throwable e) { exception = new IOException(e.getMessage()); exception.initCause(e); retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } if (!retry) { throw new HttpException(exception); } } }
可知:希望retry的情况是boolean retryRequest(IOException var1, int var2, HttpContext var3);
这里catch住的异常应该是IOException的子类,并且,如果是我们希望retry的异常,我们要人工的将catch的异常转化成IOException异常。
最终抛出HttpException。