XUtils源码分析之HttpUtils(一)

来源:互联网 发布:linux怎么显示文件类型 编辑:程序博客网 时间:2024/06/11 18:27

一、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的构造之后,用户能够进行自定义的某些功能的配置。

http_0

二、send(并行方式进行request请求)

1、HttpRequest请求的构造

>

1.1、HttpRequest extends HttpRequestBase implements HttpEntityEnclosingRequest使用apache的HttpRequestBase类,该类提供了构造HttpRequest的基本属性和方法,并实现了HttpEntityEnclosingRequest这个接口,该接口中定义了getEntitysetEntity方法,方便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请求的处理

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) { 
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult(this, result));
message.sendToTarget();
return result;
}
中将最后结果的值使用Handler传递给MainThread。

3、以上就是send(并行)方法执行的过程。

##三、sendSync(同步)执行请求。###1、同步请求比较简单,大概步骤就是:####1.1、cache将运行的结果存储在LRUCache中;下次执行一个对资源URI的请求的时候,先从cache中找到结果,如果能找到,就直接返回,否则执行网络请求。 ####1.2、进行retryHandler的对象的建立,执行网络请求的时候,如果出现了一些希望重连的情况,要不断的进行重连。所以,这部分网络的请求,要使用while(true)的循环不断重连。####1.3、在遇到我们不希望重连的情况的时候,直接抛出异常,中断执行,跳出while循环。

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。

1.5、需要注意的是:只有GET请求这类幂等性的请求,才能进行retry重连。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 c盘拒绝粘贴文件怎么办 oracle数据库密码忘了怎么办 电脑开机时不显示用户名怎么办? xp系统忘记开机密码怎么办 电脑开机密码忘了怎么办 c盘满了怎么办win10 win10电脑开机密码忘了怎么办 win10的开机密码忘了怎么办 u盘中了exe病毒怎么办 眼睛长个麦粒豆怎么办 苹果手机sdk授权失败怎么办 小米5王者荣耀卡怎么办 华为p9手机电池不耐用怎么办 华为g9青春版耗电快怎么办 华为手机摄像头坏了怎么办 华为p10摄像头玻璃划痕怎么办? 华为g9手机音量小怎么办 华为7pius太卡怎么办 华为畅享7plus卡怎么办 华为p9屏幕进水变颜色怎么办? 玩王者荣耀卡退怎么办 华为手机忘记开机密码怎么办 华为p9密码忘了怎么办 华为p9解锁密码忘了怎么办 华为手机不支持联通4g怎么办 酷派手机自动下载软件怎么办 小米5a不能开机怎么办 华为手机的视频找不到了怎么办 华为p8内存文件打不开怎么办 华为荣耀9网速慢怎么办 荣耀9手机网速慢怎么办 联想台式机不支持xp驱动怎么办 一体机尾插坏了怎么办 华为手机触屏失灵怎么办 华为p8max手机老是卡怎么办 手机屏碎了数据怎么办 华为p9屏碎了怎么办 华为p7一l09卡顿怎么办 华为p7打不开机怎么办 华为8主板坏了怎么办 华为手机主板坏了怎么办