okhttp3基本使用

优点:

1、支持HTTP/2,允许所有同一个主机地址上的请求,共享同一个socket链接

2、连接池——减少请求延时

3、透明的gzip压缩——减少响应数据的大小,减少流量并提高效率

4、缓存响应内容,避免一些完全重复的请求

网络出现问题,okhttp会自动尝试配置的其他ip。Okhttp使用TLS(SNI,ALPN)技术初始化新的连接,当握手失败时会退到TLS1.0.

那么,什么是TLS SNI ALPN 呢?

网络分为七层:

TLS/SSL是在传输层之上应用层之下。但是这个需要CA,如果想让自己的服务也支持HTTPS,那么就要去CA注册寄己的域名。有一些是免费的,比如:GoDaddy, Let’s Encrypt, CloudFlare 等。

看见了么,SNI和ALPN是TLS众多扩展协议中的两种。

导入

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

现在是3.11.0,具体的请根据官网导入官方地址 https://github.com/square/okhttp

okhttp使用一般是用okhttpClient去newCall,但是需要一个request参数。然后再用call去操作下面具体的内容

1、异步get:

/**
         * 异步get
         */

        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        Request request = builder.url(url).get().build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(Tag, "onFailure");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d(Tag, "onResponse: "+response.body().string());
            }
        });

2、同步get:

/**
         * 同步get 会阻塞,要新建线程
         */
        OkHttpClient okHttpClient1 = new OkHttpClient();
        Request.Builder builder1 = new Request.Builder();
        Request request1 = builder1.url(url).get().build();
        final Call call1 = okHttpClient1.newCall(request1);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response response = call1.execute();
                    Log.d(Tag, "同步get: " + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

3、POST方式提交String

     post方式需要提交一个请求体,这个请求体是放在请求里的,而且需要指定具体类型

     

/**
         * post 提交string
         */
        final MediaType mediaType = MediaType.parse("text/x-markdown;charset=utf-8");
        //发送给服务器的String内容
        final String content = "Love";
        final Request request = new Request.Builder().url("https://api.github.com/markdown/raw").post(new RequestBody() {
            @Override
            public MediaType contentType() {
                return mediaType;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                sink.writeUtf8(content);
            }
        }).build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(Tag, "onFailure: "+e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Headers headers = response.headers();
                for (int i=0;i<headers.size();i++){
                    Log.d(Tag, headers.name(i) + ";" + headers.value(i));
                }
                Log.d(Tag, "onesponse:" + response.body().toString());
            }
        });

4、POST提交流

/**
         * post方式提交流
         */
        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody requestBody = new RequestBody() {
            @Override
            public MediaType contentType() {
                return MediaType.parse("text/x-markdown;charset=utf-8");
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                sink.writeUtf8("love");
            }
        };
        Request request = new Request.Builder().url("https://api.github.com/markdown/raw").post(requestBody).build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(Tag, "onFailure: "+e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Headers headers = response.headers();
                for (int i=0;i<headers.size();i++){
                    Log.d(Tag, headers.name(i) + ";" + headers.value(i));
                }
                Log.d(Tag, "onResponse:" + response.body().string());
            }
        });

5、POST提交文件

/**
         * post提交文件
         */
        File file = new File(getFilesDir().getPath().toString()+"/test.md");
        boolean newFile = false;
        if (!file.exists()){
            try {
                newFile= file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("newFile: "+newFile);
        System.out.println();

        OkHttpClient okHttpClient = new OkHttpClient();
        MediaType mediaType = MediaType.parse("text/x-markdown;charset=utf-8");
        Request request = new Request.Builder().url("https://api.github.com/markdown/raw")
                .post(RequestBody.create(mediaType,file))
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(Tag, "onFailure: "+e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Headers headers = response.headers();
                for (int i=0;i<headers.size();i++){
                    Log.d(Tag, headers.name(i) + ";" + headers.value(i));
                }
                Log.d(Tag, "onResponse:" + response.body().string());
            }
        });

6、post提交表单

/**
         * post提交表单
         */
        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody requestBody = new FormBody.Builder()
                .add("testname","testpassword")
                .build();
        Request request=new Request.Builder()
                .url("https://en.wikipedia.org/w/index.php")
                .post(requestBody)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(Tag, "onFailure: "+e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Headers headers = response.headers();
                for (int i=0;i<headers.size();i++){
                    Log.d(Tag, headers.name(i) + ";" + headers.value(i));
                }
                Log.d(Tag, "onResponse:" + response.body().string());
            }
        });

7、post提交分块请求

 /**
         * post提交分块请求
         */
        OkHttpClient okHttpClient = new OkHttpClient();
        File file = new File(getFilesDir().getPath().toString()+"/test.png");
        boolean newFile = false;
        if (!file.exists()){
            try {
                newFile= file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("newFile: "+newFile);
        System.out.println();

        RequestBody body=new MultipartBody.Builder("AaB03x")
                .setType(MultipartBody.FORM)
                .addPart(
                        Headers.of("Content-Disposition","form-data;name=\"title\""),
                        RequestBody.create(null,"Square Logo")
                )
                .addPart(Headers.of("Content-Disposition","form-data;name=\"image\""),
                        RequestBody.create(MEDIA_TYPE_PNG,file))
                .build();
        Request request=new Request.Builder()
                .url("https://api.imgur.com/3/image")
                .post(body)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
                public void onFailure(Call call, IOException e) {
                    Log.e(Tag, "onFailure: "+e.getMessage());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Headers headers = response.headers();
                    for (int i=0;i<headers.size();i++){
                        Log.d(Tag, headers.name(i) + ";" + headers.value(i));
                    }
                    Log.d(Tag, "onResponse:" + response.body().string());
                }
        });

8、拦截器-interceptor

两类:全局interceptor——通过OkHttpClient.Builder#addInterceptor(Interceptor) 传入

        非网页请求interceptor——

 

参考文献:https://www.jianshu.com/p/da4a806e599b

这类拦截器只会在非网页请求中被调用,并且是在组装完请求之后,真正发起网络请求前被调用,所有的 interceptor 被保存在 List<Interceptor> interceptors 集合中,按照添加顺序来逐个调用,具体可参考 RealCall#getResponseWithInterceptorChain() 方法。通过 OkHttpClient.Builder#addNetworkInterceptor(Interceptor) 传入;

举例:

监控app通过okhttp发出的所有原始请求及整个请求耗费时间,这里使用第一类拦截器:

/**
         * 拦截器 第一类 监控原始请求信息和耗费时间
         */
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new LoggingInterceptor())
                .build();
        Request request=new Request.Builder()
                .url("http://www.publicobject.com/helloworld.txt")
                .header("User-Agent","Okhttp Example")
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });


    }

    private class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            long startTime = System.nanoTime();
            Log.d(Tag, String.format("Sending request %s on %s%n%s"
                    , request.url(), chain.connection(),request.headers()));
            Response response = chain.proceed(request);
            long endTime = System.nanoTime();
            Log.d(Tag, String.format("Received response for %s in %.1fms%n%s",
                    response.request().url(), (endTime - startTime) / 1e6d, response.headers()));

            return response;
        }
    }


其实还是有疑问的。。比如原作者的

Received response for %s in %.1fms%n%s  对应的 1e6d

个人分析应该是一种时间转换方法。

毕竟System.nanoTime()是按纳秒计算的

另外,当你把addInterceptor换为addNetworkInterceptor,你会发现他的重定向你也能看到啦。

9、自定义dns服务

默认是使用系统的

另外一般okHttpClient是使用单例的,因为他有线程池。

另外每一个call只能执行一次否则会报异常。具体参见RealCall#execute()。

再次对原作者表示感谢,这里只是用于学习记录和总结。来源:https://www.jianshu.com/p/da4a806e599b

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值