xutils的 httpUtils讲解

xUtils是github上的一个Android开源工具项目,其中HttpUtils模块是处理网络连接部分,刚好最近想整理下Android网络编程知识,今天学习下xUtils中HttpUtils.

xUtils项目地址: https://github.com/wyouflf/xUtils

先看看分析的时序图,了解下基本的过程


1. Activity创建HttpUtils对象

HttpUtils http = new HttpUtils();

查看HttpUtils类的构造函数

public HttpUtils() {
    this(HttpUtils.DEFAULT_CONN_TIMEOUT);
  }

  public HttpUtils(int connTimeout) {
    HttpParams params = new BasicHttpParams();

    ConnManagerParams.setTimeout(params, connTimeout);
    HttpConnectionParams.setSoTimeout(params, connTimeout);
    HttpConnectionParams.setConnectionTimeout(params, connTimeout);

    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);

    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);
        }
      }
    });

    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;
            }
          }
        }
      }
    });
  }
这里主要是设置HttpParams参数,然后创建httpClient对象。

注意这个类ThreadSafeClientConnManager,它主要是为了使用线程安全的连接管理来创建HttpClient。

不过这里就有个疑问了,之前看资料了解到一般创建HttpClient都是用的 单例模式,说是一个httpClient就相当于是一个小型的浏览器,如果创建多个httpClient就很消耗资源了,我看了这个开源项目给的demo,是创建一个请求就创建一个HttpClient, 到时跟作者联系看看是什么回事。

2.发送请求

 http.send(HttpRequest.HttpMethod.GET,
        "http://www.baidu.com",
        new RequestCallBack<String>() {


          @Override
          public void onStart() {
            resultText.setText("conn...");
          }


          @Override
          public void onLoading(long total, long current, boolean isUploading) {
            resultText.setText(current + "/" + total);
          }


          @Override
          public void onSuccess(ResponseInfo<String> responseInfo) {
            resultText.setText("response:" + responseInfo.result);
          }




          @Override
          public void onFailure(HttpException error, String msg) {
            resultText.setText(msg);
          }
        });
调用send方法发生请求,

HttpRequest.HttpMethod.GET指明请求的方式,

"http://www.baidu.com"请求的地址,

new RequestCallBack<String>()请求的回调函数,这里面四个方法方便开发者处理请求的各个阶段的结果。

3. http.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);
    }
    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);

  handler.executeOnExecutor(executor, request);
  return handler;
    }
查看httpUtils的send函数,发现最后会调用sendRequest函数

在sendRequest里创建HttpHandler对象

4. HttpHandler

HttpHandler<T> extends CompatibleAsyncTask<Object, Object, Void> implements RequestCallBackHandler

参看httpHandler发现它继承CompatibleAsyncTask

5.CompatibleAsyncTask

查看CompatibleAsyncTask ,发现它是A compatible AsyncTask for android2.2.你懂得

6.handler.executeOnExecutor(executor, request)

在第3步里创建完httpHandler后,调用handler.executeOnExecutor(executor, request),而通过第4步了解到httpHandler继承CompatiableAsyncTask, 就先去看看doInBackground里做了什么事情。

7.doInBackground(Object... params)

 //先处理传递进来的params
  
  this.publishProgress(UPDATE_START);


  lastUpdateTime = SystemClock.uptimeMillis();


  ResponseInfo<T> responseInfo = sendRequest(request);
  if (responseInfo != null) {
      this.publishProgress(UPDATE_SUCCESS, responseInfo);
      return null;
  }
先处理传递进来的params,调用publishProgress更新下当前的状态,然后调用sendRequest

8.sendRequest(HttpRequestBase request)

private ResponseInfo<T> sendRequest(HttpRequestBase request) throws HttpException {


    HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();
    while (true) {

        requestMethod = request.getMethod();
        if (HttpUtils.sHttpCache.isEnabled(requestMethod)) {
          String result = HttpUtils.sHttpCache.get(requestUrl);
          if (result != null) {
            return new ResponseInfo<T>(null, (T) result, true);
          }
        }


        ResponseInfo<T> responseInfo = null;
        if (!isCancelled()) {
          HttpResponse response = client.execute(request, context);
          responseInfo = handleResponse(response);
        }
        return responseInfo;
      } catch (Exception e) {
        exception = e;
        retry = retryHandler.retryRequest(exception, ++retriedCount, context);
      } 
      if (!retry) {
        throw new HttpException(exception);
      }
    }
  }
这个方法仔细看看,

先获取下client.getHttpRequestRetryHandler(),获取retry的设置

requestMethod = request.getMethod();
                if (HttpUtils.sHttpCache.isEnabled(requestMethod)) {
                    String result = HttpUtils.sHttpCache.get(requestUrl);
                    if (result != null) {
                        return new ResponseInfo<T>(null, (T) result, true);
                    }
                }
如果使用了缓存则通过requestUrl去httpCache去获取,获取到了则创建ResponseInfo对象

如果没有缓存

HttpResponse response = client.execute(request, context);
                    responseInfo = handleResponse(response);
调用httpClient执行http请求,获取到得结果交由handleResponse处理

如果之前的处理出现异常则

retry = retryHandler.retryRequest(exception, ++retriedCount, context);
调用retry机制,直到有结果,或者超过retry的次数

9.handleResponse()

第8步的时候,如果client执行获取到结果则调用handleResponse(HttpResponse response)处理结果

ResponseInfo<T> handleResponse(HttpResponse response) throws HttpException, IOException {

    StatusLine status = response.getStatusLine();
    int statusCode = status.getStatusCode();
    if (statusCode < 300) {
  
          result = mStringDownloadHandler.handleEntity(entity, this, charset);
          if (HttpUtils.sHttpCache.isEnabled(requestMethod)) {
            HttpUtils.sHttpCache.put(requestUrl, (String) result, expiry);
          }
        
      }
      return new ResponseInfo<T>(response, (T) result, false);
    } else if (statusCode == 301 || statusCode == 302) {
      if (httpRedirectHandler == null) {
        httpRedirectHandler = new DefaultHttpRedirectHandler();
      }
      HttpRequestBase request = httpRedirectHandler.getDirectRequest(response);
      if (request != null) {
        return this.sendRequest(request);
      }
    } 
    return null;
  }
这个方法主要根据返回的statuscode处理,<300将结果存在HttpCache里,301或者302则处理重定向

10.publishProgress(UPDATE_SUCCESS, responseInfo)

在获得ResponseInfo后,调用 publishProgress(UPDATE_SUCCESS, responseInfo) 方法,最后会调用onProgressUpdate方法

protected void onProgressUpdate(Object... values) {
      case UPDATE_SUCCESS:
        if (values.length != 2) return;
        this.state = State.SUCCESS;
        callback.onSuccess((ResponseInfo<T>) values[1]);
        break;
      default:
        break;
    }
  }
这onProgressUpdate里发现最终调用第2步传进来的callback

整个的调用过程基本上是这样。

1.创建httputils时创建httpClient,调用send发送请求

2. 调用send时,创建httpHandler,此类继承CompatibleAsyncTask

3.在httpHandler的doInBackground真正的处理http请求,此时会判断是否有缓存,获取结果后,通过回调处理结果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值