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方法,使得一次请求就完成了;

0 0
原创粉丝点击