• OKHTTP 简单分析


      

    内部使用了OKIO库, 此库中Source表示输入流(相当于InputStream),Sink表示输出流(相当于OutputStream)

        特点:

        ·既支持同步请求,也支持异步请求,同步请求会阻塞当前线程,异步请求不阻塞当前线程,异步执行完成后回掉相应的方法

        ·支持HTTP/2协议,通过HTTP/2 可以让客户端中到服务器的所有请求共用同一个Socket连接

        ·非HTTP/2 请求时, OKHTTP内部会维护一个线程池,通过线程池可以对HTTP/1.x的连接进行复用,减少延迟

        ·透明的Gzip处理降低了通信数据的大小

        ·请求的数据可以进行缓存

     

    重要的类:

       ·Request 请求类,OKHTTP中大量使用了Builder构建器模式,Request也不例外,其内部有静态内部类Builder, 封装了请求url,请求方法method,请求头headers, 请求体RequestBody,请求标记tag

        ·Headers类, 被封装在Request或Response中,其内部使用一维数组String[] namesAndValues表示header的key value信息,可以看到除了导入包中的Util、HttpDate类之外,跟OKHTTP的关联并不大,可以将此类copy出来单独分析。在Builder内部类中有一个ArrayList<String> namesAndValues

    ,当我们添加header键值对时,调用add方法,最终调用addLenient()方法将name,value的值依次添加到列表中,列表内部按照name,value,name2,value2,name3,value3...的顺序排列,在build()方法中调用toArray方法再转换为String数组,内部元素的顺序不变,这样在用get方法查找的时候

    private static String get(String[] namesAndValues, String name) {
        for (int i = namesAndValues.length - 2; i >= 0; i -= 2) {
          if (name.equalsIgnoreCase(namesAndValues[i])) {
            return namesAndValues[i + 1];
          }
        }
        return null;
      }
    

      

    可以先查找对应的name,得到name对应的索引后,那么value是紧随name其后的,自然可以得到value的值。且在查找的时候i的值可以每隔2做一次处理。这样有些巧妙的设计,避免使用Map去存储键值对,一定程度上提高了效率。 由于在调用get方法时是倒序查找,故添加相同的字段时,取最后一个的值。如果使用set(String name, String value) 则会移除旧的name和value。需要注意的是有时候响应头含有多个重复name的header, 比如有个多 Set-Cookie,这时候可以调用 values(String name)便可以获得多个值。

        ·ResponseBody 内部使用了OKIO, 可以得到字节数组 bytes(), 字符串结果string(),或者是输入流 byteStream, 特别需要注意的是bytes() string() 方法的注释,这两个方法会将响应实体内容全部加载到内存中,所以如果响应实体比较大的话,应该考虑使用流的形式读取。其中charStream()使用响应头Content-Type指定的字符集来解析响应体。默认是UTF-8

     

    Call

        同步方法execute() 会阻塞当前线程直到有响应。

        异步方法 enqueue(Callback responseCallback)

     

    OKHttpClient

        内部也使用Builder构建器模式,可以配置超时时间,缓存,代理,拦截器等

     

    Force a Network Response

        在某些情形下,例如点击了刷新按钮之后,有必要跳过缓存,直接向服务器获取资源,为了获得刷新后的资源可以 添加 Connection.addRequestProperty(“Cache-Control”, “no-cache”), 或者可以直接使用 connection.addRequestProperty(“Cache-Control”, “max-age=0”);

    Force a Cache Response

        Connection.addRequestProperty(“Cache-Control”, “only-if-cached”);

     

    请求的流程:

        ·异步请求

             创建Request ,执行client.newCall(request).enqueue(Callback)方法,跟踪newCall方法,方法内部new了一个RealCall,RealCall实现了Call接口,查看RealCall的enqueue方法,最终调用client.dispatcher().enqueue(new AsyncCall(responseCallback);其中Dispatcher内部封装了线程池(可以看到默认的线程池也是没有核心线程, 和Android-Async-http的默认线程池一致),查看Dispatcher的enqueue方法可以看到如果正在请求的call数量小于最大请求数,则将call添加到runningAsyncCalls中,并提交call到线程池中(AsyncCall实现了Runnable的接口), 查看AsyncCall的构造方法,可以看到传入响应的回调,AsyncCall提交到线程池中后,run方法中会调用execute方法,

    在AsyncCall的execute方法中通过getResponseWithInterceptorChain()方法得到Response,并进行响应的请求成功或失败的回调,然后调用finished方法移除之前添加到Queue中的call。

        

    上传文件:

    OkHttpClient httpClient = new OkHttpClient();
    
    RequestBody requestBody = FormBody.create(MediaType.parse("image/jpeg"),
    		new File(getExternalCacheDir()+ File.separator +"IMG_20171106_202814.jpg"));
    
    MultipartBody multipartBody = new MultipartBody.Builder()
    		.setType(MultipartBody.FORM)
    		.addFormDataPart("uploadimg", "IMG_20171106_202814.jpg", requestBody)
    		.build();
    
    Request request = new Request.Builder().url("http://www.chuantu.biz/upload.php")
    		.addHeader("Cache-Control", "max-age=0")
    		.addHeader("Upgrade-Insecure-Requests", "1")
    		.addHeader("Accept-Language","zh-CN,zh;q=0.8")
    		.post(multipartBody).build();
    
    Call call = httpClient.newCall(request);
    call.enqueue(new Callback() {
    	@Override
    	public void onFailure(Call call, IOException e) {
    	}
    
    	@Override
    	public void onResponse(Call call, Response response) throws IOException {
    
    		Log.d("song", response.body().string());
    	}
    });
    

      

    Fidddler抓包的截图

    特别声明:如果转载,请保留出处信息,感谢您的关注和推荐!!
  • 相关阅读:
    c语言 12
    c语言中用结构体表示点的坐标,并计算两点之间的距离
    c语言 12
    c语言中结构体数组
    c语言 12-3
    c语言 12-2
    codevs3164 质因数分解
    codevs4438 YJQ Runs Upstairs
    codevs4439 YJQ Requires Food
    codevs4437 YJQ Arranges Sequences
  • 原文地址:https://www.cnblogs.com/sphere/p/7810374.html
Copyright © 2020-2023  润新知