您的位置:首页 > 其它

XUtils net

2016-04-09 13:25 330 查看
首先查看用法:

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
c720
, 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方法,使得一次请求就完成了;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: