XUtils net
来源:互联网 发布:nba2k online mac 编辑:程序博客网 时间:2024/05/16 23:39
首先查看用法:
get请求:
private void getMethod() {
RequestParams params = new RequestParams();
params.addQueryStringParameter("name", "value");
HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.GET, "http://...", params,new RequestCallBack<Object>() {
@Override
public void onSuccess(ResponseInfo<Object> responseInfo) {
}
@Override
public void onFailure(HttpException error, String msg) {
}
});
}
post请求:HttpPost请求的方式和HttpGet的几乎可以说是一模一样,一样提供了各种对应不同结果的回调方法
private void postMethod() {
RequestParams params = new RequestParams();
params.addQueryStringParameter("name", "value");
params.addBodyParameter("name", "value");
HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.POST, "http://...", params, new RequestCallBack<String>() {
@Override
public void onStart() {
super.onStart();
}
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
}
@Override
public void onCancelled() {
super.onCancelled();
}
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
}
@Override
public void onFailure(HttpException error, String msg) {
}
});
}
下载文件:
private void downLoadMethod() {
HttpUtils http=new HttpUtils();
HttpHandler<File> mHandler=http.download("url",
"target",//下载完成后存储路径
true,//true表示支持断点下载
true,//表示下载完成后自动重命名
new RequestCallBack<File>() {
@Override
public void onStart() {
super.onStart();
}
@Override
public void onSuccess(ResponseInfo<File> responseInfo) {
}
@Override
public void onFailure(HttpException error, String msg) {
}
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
}
@Override
public void onCancelled() {
super.onCancelled();
}
});
}
下载过程中如果需要暂停下载,也只需简单的一行代码来实现:mHandler.stop()
上传文件:
private void upLoadMethod() {
RequestParams params = new RequestParams();
params.addQueryStringParameter("access_token", "123");
params.addBodyParameter("file", new File("path"));
HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.POST,
"url",
params,
new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
}
@Override
public void onFailure(HttpException error, String msg) {
}
});
}
源码分析:
1.首先看出核心入口就是HttpUtils类,它总共有4个构造方法:
public HttpUtils()
public HttpUtils(String userAgent)
public HttpUtils(int connTimeout)
public HttpUtils(int connTimeout, String userAgent)
主要用来设定连接超时时间以及使用的agent,在这个构造中进行了初始化:
public HttpUtils(int connTimeout, String userAgent) { HttpParams params = new BasicHttpParams(); ConnManagerParams.setTimeout(params, connTimeout);//<span style="color:#ff0000;">设定超时时间</span> HttpConnectionParams.setSoTimeout(params, connTimeout); HttpConnectionParams.setConnectionTimeout(params, connTimeout); if (TextUtils.isEmpty(userAgent)) { userAgent = OtherUtils.getUserAgent(null); } HttpProtocolParams.setUserAgent(params, userAgent); ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(10)); ConnManagerParams.setMaxTotalConnections(params, 10); HttpConnectionParams.setTcpNoDelay(params, true); HttpConnectionParams.setSocketBufferSize(params, 1024 * 8); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);//设定基于的http协议版本为1.1 SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", DefaultSSLSocketFactory.getSocketFactory(), 443)); httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, schemeRegistry), params); httpClient.setHttpRequestRetryHandler(new RetryHandler(DEFAULT_RETRY_TIMES)); httpClient.addRequestInterceptor(new HttpRequestInterceptor() { @Override public void process(org.apache.http.HttpRequest httpRequest, HttpContext httpContext) throws org.apache.http.HttpException, IOException { if (!httpRequest.containsHeader(HEADER_ACCEPT_ENCODING)) { httpRequest.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP); } } });<span style="color:#ff0000;">//添加请求时拦截器</span> httpClient.addResponseInterceptor(new HttpResponseInterceptor() { @Override public void process(HttpResponse response, HttpContext httpContext) throws org.apache.http.HttpException, IOException { final HttpEntity entity = response.getEntity(); if (entity == null) { return; } final Header encoding = entity.getContentEncoding(); if (encoding != null) { for (HeaderElement element : encoding.getElements()) { if (element.getName().equalsIgnoreCase("gzip")) { response.setEntity(new GZipDecompressingEntity(response.getEntity())); return; } } } } });<span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">//添加response时拦截器</span> }
2.顺藤摸瓜,post,get,以及文件上传都是Httputils暴漏出来的send方法:有两个重载的方法:最后都调用了第二个方法
public <T> HttpHandler<T> send(HttpRequest.HttpMethod method, String url,
RequestCallBack<T> callBack) {
return send(method, url, null, callBack);
}
public <T> HttpHandler<T> send(HttpRequest.HttpMethod method, String url, RequestParams params,
RequestCallBack<T> callBack) {
if (url == null) throw new IllegalArgumentException("url may not be null");
HttpRequest request = new HttpRequest(method, url);
return sendRequest(request, params, callBack);
}
从第二个方法可知它根据传入参数创建获得实体HttpRequest然后调用sendRequest
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;
}
从上可知,所有的请求操作由类HttpHandler来进行处理:
参数EXECUTOR是一个Executor维持着一个线程池
而对于HttpHandler的继承关系图
主要是执行handler.executeOnExecutor(EXECUTOR, request)这一方法来进行实际的请求,调用的是,
exec.execute(new PriorityRunnable(priority, mFuture));
exec指向的是子类private final static PriorityExecutor EXECUTOR = new PriorityExecutor(DEFAULT_POOL_SIZE);也就是说默认是维持着3个线程的线程池;这个过程中调用了
mThreadPoolExecutor.execute(r);mThreadPoolExecutor是一个
private final ThreadPoolExecutor mThreadPoolExecutor;它在PriorityExecutor构造过程中进行初始化:
mThreadPoolExecutor = new ThreadPoolExecutor(
poolSize,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE,
TimeUnit.SECONDS,
mPoolWorkQueue,
sThreadFactory);
几个参数的含义:
poolSize:corePoolSize the number of threads to keep in the pool, even if they are idle, unless {@code allowCoreThreadTimeOut} is set;就是说它至少维持的线程数,就算是没有进行网络操作也会保持3个线程;
MAXIMUM_POOL_SIZE:线程池中最大线程数:默认为256个
keepAliveTime:when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.意思就是当你的线程池中的线程大于核心数的线程,当该线程执行完毕后被回收等待的时长,xutils默认为1秒
TimeUnit.SECONDS:时间单位
workQueue the queue to use for holding tasks before they are executed. This queue will hold only the {@code Runnable} tasks submitted by the {@code execute} method.
存放待执行任务的线程队列
ThreadFactory:线程工厂,负责制造线程
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; }
exec.execute(new PriorityRunnable(priority, mFuture))
exec是 private final static PriorityExecutor EXECUTOR = new PriorityExecutor(DEFAULT_POOL_SIZE);
mFuture是存放的待执行任务:
mFuture是什么时候初始化的呢?
/**
* 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);
}
}
};
}
它是HttpHandler的构造方法,也就是说在创建HttpHandler时进行了mFuture和mWorker的初始化,因为是在父类的空参构造中初始化的,子类创建时都会默认调用父类的空参构造方法。
我们看它在初始化的过程中主要做了什么:
1.创建了一个WorkerRunnable,它有一个待实现的方法call():在call被调用的过程中设置了线程的优先级:
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);然后调用了doInBackground(Params... params)方法,这是一个待实现方法,走的是实现子类的方法,这里走的是HttpHandler的方法:我们查看这个方法:
@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; }
可以看出执行请求的方法是 :sendRequest(HttpRequestBase request):
其方法内部执行
HttpResponse response = client.execute(request, context);
responseInfo = handleResponse(response);
在handleResponse里失败的话又根据设定的重复请求个数进行了重复的请求
2.创建了FutureTask,而在FutureTask的构造中将mWoker传入进去
再回头看
exec.execute(new PriorityRunnable(priority, mFuture))它其实最后执行的是mFuture的run方法;
那么我们看mFuture的run方法是怎么写的:
public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }其中的callable也就是传过去的mWorker
result = c.call();这是关键的代码,在这里回调了mWorker的call方法,使得一次请求就完成了;
- XUtils net
- xUtils
- XUtils
- xUtils
- XUtils
- xUtils
- xUtils
- XUtils
- xutils
- xUtils
- xUtils
- XUtils
- xUtils
- xutils
- XUtils
- XUtils
- Xutils
- xUtils
- android.hardware.camera2使用指南
- latex学习3:教你如何在word中像LaTex那样打公式
- jquery的html,text,val
- FZUOJ-2128 最长子串(strstr函数枚举暴力)
- 深入理解javascript原型和闭包系列 深入理解javascript原型和闭包(1)——一切都是对象
- XUtils net
- 树状数组
- android开发之SearchView
- 阅读STL源码剖析笔记 —— 迭代器概念
- Z字形扫描
- Redis监控工具—Redis-stat、RedisLive
- 在Ubuntu平台下编译比特币bitcoin客户端
- 0 / 1 背包问题--动态规划(附详细注释)
- FORM表单 validity setCustomValidity和checkValidity使用