Android OKHttp使用简介

下面是官网给出的OKHTTP的特点:

  1. 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据;
  2. 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时;
  3. 透明的Gzip处理降低了通信数据的大小
  4. 响应缓存完全避免了网络中的重复请求
  5. 使用Okio来简化数据的访问与存储,提高性能
  6. 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP
  7. OkHttp还处理了代理服务器问题和SSL握手失败问题;

官网地址:square.github.io/okhttp/

配置

添加OKHttp依赖

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

添加网络权限,如果需要文件读写文件读写权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

接下来就可以愉快的开始使用OKhttp进行开发了。

创建OkHttpClient

OKhttpclient通过builder构建,构建的时候涉及到很多配置项,本次简单对其中一些配置项做了说明,后续会对一些重要的配置项做专题说明。在实际的项目中的配置项根据项目具体需求进行配置。

    OkHttpClient.Builder builder = new OkHttpClient.Builder();

    //缓存目录
    File externalCacheDir = context.getExternalCacheDir();
    if (externalCacheDir != null) {
        Cache okHttpCache = new Cache(new File(externalCacheDir,
                "HttpCache"), 30 * 1024 * 1024);
        builder.cache(okHttpCache);
    }

    //连接超时时间,连接超时是在将TCP SOCKET 连接到目标主机时应用的,默认10s
    builder.connectTimeout(30, TimeUnit.SECONDS);
    //读取超时时间, 包括TCP SOCKET和Source 和Response的读取IO操作,默认10s
    builder.readTimeout(20, TimeUnit.SECONDS);
    //写入超时时间,主要指IO的写入操作,默认10s
    builder.writeTimeout(20, TimeUnit.SECONDS);
    //整个调用时期的超时时间,包括解析DNS、链接、写入请求体、服务端处理、以及读取响应结果
    builder.callTimeout(120, TimeUnit.SECONDS);

    //用于单个client监听所有解析事件的,可以用于解析耗时计算
    builder.eventListener(EventListener.NONE);

    //添加拦截器,框架内部已经默认添加了部分拦截器,通过接口添加的拦截器在列表首部
    builder.addInterceptor(new LogInterceptor());
    //添加网络拦截器,网络拦截器可以操作重定向和失败重连的返回值,以及监控所有的网络数据
    builder.addNetworkInterceptor(new NetworkInterceptor());

    //在握手期间,如果URL的主机名和服务器的标识主机名不匹配,验证机制可以回调此接口的实现者,以确定是否应该允许此连接。
    //返回false表示不允许此链接,无脑return true 十分不安全
    builder.hostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

//授权,默认为Authenticator.NONE
//        builder.authenticator(Authenticator.NONE);

//连接池,默认5个空闲连接,连接保活5分钟
//        builder.connectionPool(new ConnectionPool());

//自定义CookieJar,默认CookieJar.NO_COOKIES
//        builder.cookieJar(CookieJar.NO_COOKIES);

//调度策略,默认最大并发数默认为 64,但个域名最大请求数 默认为 5 个
//        builder.dispatcher(new Dispatcher());

//配置证书认证策略
//        builder.sslSocketFactory();

      OkHttpClient  client = builder.build();

上述配置项中比较常用的有

  1. 缓存文件路径以及缓存的容量大小
  2. 网络请求的链接、读取、写入的超时时间
  3. 拦截器,这个是OKHTTP最常用的,可以用于处理包括重试、缓存、日志打印等功能
  4. 域名和证书的校验
  5. 连接器以及并发的调度策略等

同步get请求

public void synGet(String url) {

        // 第一步,构建HttpUrl
        HttpUrl.Builder builder = null;
        try {
            HttpUrl httpUrl = HttpUrl.parse(url);
            if(httpUrl != null){
                builder = httpUrl.newBuilder();
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }

        if (builder == null) {
            return;
        }
        builder.addQueryParameter("key","value");

        // 第二步,构建Request请求对象
        Request request = new Request.Builder()
                //请求地址
                .url(httpUrl)
                //get请求,默认为get请求
                .get()
                //添加请求头,一个key对应多个value,可以自定义
                .addHeader("key", "value")
                .addHeader("key", "value1")
                //请求头,一对一的,如常见的Content-Type、Accept-Encoding等
                .header("key1", "value1")
                //缓存策略,当前使用强制网络请求
                .cacheControl(CacheControl.FORCE_NETWORK)
                //缓存策略
                .build();

        try {
            //第三步,开始进行同步请求
            Response response = client
                    .newCall(request)
                    .execute();

            //第四步,解析响应结果
            ResponseBody body = response.body();
            if (body != null) {
                Log.d(TAG, body.string());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

同步get请求会阻塞当前线程直到返回结果,请求大致分为四个步骤:

  1. 构建HttpUrl,当然这一步不是必须的,也可以直接传入地址
  2. 第二步,构建Request请求对象,可以设置请求头,缓存策略,请求方式
  3. 第三步,开始进行同步请求
  4. 解析响应结果

注意:同步get请求要在子线程中进行,否应用会抛异常。

异步get请求

异步请求方式的步骤和上述前两个步骤基本一致,主要发起请求的方式发生了变化,结果通过回调返回。这种请求方式对请求的线程没有限制。

// 第一步,构建HttpUrl
// 第二步,构建Request请求对象
//第三步,开始进行异步请求
client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //第四步,解析响应结果
                ResponseBody body = response.body();
                if (body != null) {
                    Log.d(TAG, body.string());
                }
            }
        });

同步post请求

public void synPost(String url) {
    // 第一步,构建HttpUrl
    HttpUrl.Builder builder = null;
    try {
        HttpUrl httpUrl = HttpUrl.parse(url);
        if (httpUrl != null) {
            builder = httpUrl.newBuilder();
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    }
    if (builder == null) {
        return;
    }

    //第二步,构建RequestBody
    MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
    JSONObject jsonObject = new JSONObject();
    try {
        jsonObject.put("key1", "value1");
        jsonObject.put("key2", "value2");
    } catch (JSONException e) {
        e.printStackTrace();
    }
    RequestBody requestBody = RequestBody.create(mediaType, jsonObject.toString());
    // 第三步,构建Request请求对象
    Request request = new Request.Builder()
            .url(builder.build())
            .post(requestBody)
            .build();

    //第四步,开始进行同步post请求
    try {
        Response response = client.newCall(request).execute();
        //第五步,解析请求结果
        ResponseBody body = response.body();
        if (body != null) {
            Log.d(TAG, body.string());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

与get请求方式不同的是post请求需要构建RequestBody,在请求时携带RequestBody。

异步post请求

public void asynPost(String url) {
        // 第一步,构建HttpUrl
        //第二步,构建RequestBody
        // 第三步,构建Request请求对象
        Request request = new Request.Builder()
                .url(builder.build())
                .post(requestBody)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ResponseBody body = response.body();
                if (body != null) {
                    Log.d(TAG, body.string());
                }
            }
        });
    }

上传文件

    //第一步,构建HttpUrl
    //第二步,构建RequestBody
    MediaType mediaType = MediaType.parse("multipart/form-data; charset=utf-8");
    RequestBody requestBody = RequestBody.create(mediaType, file);
	//第三步,构建MultipartBody
    MultipartBody body = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            //在此处添加多个requestBody实现多文件上传
            .addFormDataPart("file", file.getName(), requestBody)
            .build();

    // 第四步,构建Request请求对象
    Request request = new Request.Builder()
            .url(builder.build())
            .post(body)
            .build();
	// 第五步,构建Request请求对象
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            ResponseBody body = response.body();
            if (body != null) {
                Log.d(TAG, body.string());
            }
        }
    });

表单提交

	//第二步,构建RequestBody
    FormBody formBody = new FormBody.Builder()
            .add("key1","value1")
            .add("key2","value2")
            .build();

    // 第三步,构建Request请求对象
    Request request = new Request.Builder()
            .url(builder.build())
            .post(formBody)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            ResponseBody body = response.body();
            if (body != null) {
                Log.d(TAG, body.string());
            }
        }
    });

以上就是OKHttp 使用简介的详细内容,更多关于OKHttp 使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • android实现okHttp的get和post请求的简单封装与使用

    由于Android课程项目需要,特地查阅了okHttp的使用,发现网上找的大多和自己的需求不一样.所以就着团队项目需要,自己简单封装了一个okHttp的get和post请求. 话不多说,直接看代码吧! 一.前期需要用到的属性封装 private static Request request = null; private static Call call = null; private static int TimeOut = 120; //单例获取ohttp3对象 private static

  • 基于Feign使用okhttp的填坑之旅

    1.由于项目需要远程调用http请求 因此就想到了Feign,因为真的非常的方便,只需要定义一个接口就行. 但是feign默认使用的JDK的URLHttpConnection,没有连接池效率不好,从Feign的自动配置类FeignAutoConfiguration中可以看到Feign除了默认的http客户端还支持okhttp和ApacheHttpClient,我这里选择了okhttp,它是有连接池的. 2.看看网络上大部分博客中是怎么使用okhttp的 1).引入feign和okhttp的mav

  • Android Studio OkHttpClient使用教程详解

    本次来记录下OkHttpClient的使用,OkHttpClient是用来完成android 客户端对服务端请求的工具. 首先记住,使用网络的时候一定要加入权限,加入到AndroidMainfest.xml中 <uses-permission android:name="android.permission.INTERNET" /> 在初次使用的时候会出现报错.cannot resolve symbol OkHttpClient 这里需要引入 implementation

  • 完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题

    事发地 原默认的Feign是使用URLConnector进行通信的,当换为okhttp时,直接引入包及配置以下内容根本不生效,还是走原生的. feign: okhttp: enable: true 事件还原 创建项目并引入pom相关的依赖如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xml

  • Android okhttp的启动流程及源码解析

    前言 这篇文章主要讲解了okhttp的主要工作流程以及源码的解析. 什么是OKhttp 简单来说 OkHttp 就是一个客户端用来发送 HTTP 消息并对服务器的响应做出处理的应用层框架. 那么它有什么优点呢? 易使用.易扩展. 支持 HTTP/2 协议,允许对同一主机的所有请求共用同一个 socket 连接. 如果 HTTP/2 不可用, 使用连接池复用减少请求延迟. 支持 GZIP,减小了下载大小. 支持缓存处理,可以避免重复请求. 如果你的服务有多个 IP 地址,当第一次连接失败,OkHt

  • SpringCloud Open feign 使用okhttp 优化详解

    我就废话不多说了,大家还是直接看代码吧~ <!--web 模块 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!--排除tomcat依赖 --> <exclusion> <artifactId&

  • 解决Feign切换client到okhttp无法生效的坑(出现原因说明)

    提示:如果只看如何解决问题,请看文章的末尾如何解决这个问题 1. 场景描述 最近项目中使用了feign当做http请求工具来使用.相对于httpclient.resttemplate来说,fegin用起来方便很多. 然后项目有httptrace的需求,需要输出请求日志. 所以就开启了feign自己的日志,发现它自带的日志是debug级别才能打印.而且是逐行打印的,看日志非常的不方便.所以需要输出json格式的日志最好. 2.解决步骤 2.1 引入feign依赖 <dependency> <

  • android 使用okhttp可能引发OOM的一个点

    遇到一个问题: 需要给所有的请求加签名校验以防刷接口;传入请求url及body生成一个文本串作为一个header传给服务端;已经有现成的签名检验方法String doSignature(String url, byte[] body);当前网络库基于com.squareup.okhttp3:okhttp:3.14.2. 这很简单了,当然是写一个interceptor然后将request对象的url及body传入就好.于是有: public class SignInterceptor implem

  • 使用SpringBoot+OkHttp+fastjson实现Github的OAuth第三方登录

    一.在GitHub上创建一个OAuth 二.OAuth的原理 Spring官方文档 三.OkHttp的使用 OkHttp官方网站 1.Post 代码示例 //官方文档: public static final MediaType JSON // = MediaType.get("application/json; charset=utf-8"); MediaType mediaType = MediaType.get("application/json; charset=ut

  • Android的简单前后端交互(okHttp+springboot+mysql)

    前言 前阵子发现了个有意思又好用的框架--okHttp.由于课程设计需要,无意间发现了这个框架,打算利用此框架与后端交互,可以参考前后端分离的项目,把android当做前端,springboot当做后端,以下是二者的简单交互. okHttp说明 (1)android网络框架之OKhttp 一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso) 用于替代HttpUrlConnection和Apache HttpClient (2)ok

  • SpringBoot 配置 okhttp3的操作

    1. Maven 添加依赖 <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.10.0</version> </dependency> 2. application.properties 配置文件 ok.http.connect-timeout=30 ok.http.re

随机推荐