OKHttp 使用 Android OKHttp使用简介
Soybeanmilk 人气:0想了解Android OKHttp使用简介的相关内容吗,Soybeanmilk在本文为您仔细讲解OKHttp 使用的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:OKHttp,使用,Android,OKHttp,下面大家一起来学习吧。
下面是官网给出的OKHTTP的特点:
- 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据;
- 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时;
- 透明的Gzip处理降低了通信数据的大小
- 响应缓存完全避免了网络中的重复请求
- 使用Okio来简化数据的访问与存储,提高性能
- 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP
- OkHttp还处理了代理服务器问题和SSL握手失败问题;
配置
添加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();
上述配置项中比较常用的有
- 缓存文件路径以及缓存的容量大小
- 网络请求的链接、读取、写入的超时时间
- 拦截器,这个是OKHTTP最常用的,可以用于处理包括重试、缓存、日志打印等功能
- 域名和证书的校验
- 连接器以及并发的调度策略等
同步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请求会阻塞当前线程直到返回结果,请求大致分为四个步骤:
- 构建HttpUrl,当然这一步不是必须的,也可以直接传入地址
- 第二步,构建Request请求对象,可以设置请求头,缓存策略,请求方式
- 第三步,开始进行同步请求
- 解析响应结果
注意:同步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()); } } });
加载全部内容