在这里先来个重要的说明:网络权限一定要加,一定要加!!!
其实关于OkHttp的使用只要记住一个顺序就可以
- 创建OkHttpClient对象
- 创建请求Request内容
- 发送请求
- 创建请求的回调
基本上记住上面的步骤就可以实现简单的请求了!
1.1 简单的GET请求
既然上面都提到了相应的步骤,我们就按照上面的步骤写一下就可以了!!!
1.1.1 创建OkHttpClient对象
OkHttpClient httpClient = new OkHttpClient();
创建一个对象而已,没有什么好说的!!!
1.1.2 创建请求Request内容
Request request = new Request.Builder()
.method("GET", null)
.url("https://www.baidu.com/")
.build();
这里简单说一下,method是设置相应的请求方式的;url是设置相应的请求地址的!其次Request是一个构建者的构建模式。剩下的没有什么好说的。,如果新手,不用管那么多为什么,实现效果才是重要的!!!
1.1.3 发送请求
Call call = httpClient.newCall(request);
这里其实就是让httpClient知道自己要请求什么而已
1.1.4 创建请求返回的内容
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "请求失败的原因:" + e);
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
Headers headers = response.headers();
Set<String> names = headers.names();
for (String name : names) {
Log.e(TAG, "请求的header" + name);
String value = headers.get(name);
Log.e(TAG, "值为: " + value + "\n----------------------------------");
}
final String date = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
mTvShow.setText(date);
}
});
}
});
这里要说明的就多了:
-
当你的看到FATAL EXCEPTION: OkHttp Dispatcher这个异常的时候,恭喜你,你踩到第一个坑了!这个主要是因为
response.body().string()
只能调用一次,如果你在代码中调用了两次,那么就会出现上面的异常; -
当你异步请求的时候,是不能在子线程修改UI的,所以这里我用了一个Handler去操作相应的内容
-
如果你想看相应的一些内容的话,那么看那个for循环那里,你打印一下,就能看到如下的内容,如果不怎么理解的话,找你们后台人员请教一下!一定要虚心哦。
Accept-Ranges →bytes Cache-Control →no-cache Connection →Keep-Alive Content-Length →227 Content-Type →text/html Date →Wed, 05 Sep 2018 03:41:58 GMT Etag →"5b7b7f40-e3" Last-Modified →Tue, 21 Aug 2018 02:56:00 GMT Pragma →no-cache Server →BWS/1.1 Set-Cookie →BD_NOT_HTTPS=1; path=/; Max-Age=300 Strict-Transport-Security →max-age=0 X-Ua-Compatible →IE=Edge,chrome=1
-
如果失败的话,那么就会在onFailure中把异常反馈给你!!!
给你贴下整体代码吧!
/*1.创建OkHttpClient对象*/
OkHttpClient httpClient = new OkHttpClient();
/*2.创建请求Request内容*/
Request request = new Request.Builder()
.method("GET", null)
.url("https://www.baidu.com/")
.build();
/*3.发送请求*/
Call call = httpClient.newCall(request);
/*4.创建请求的回调*/
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "请求失败的原因:" + e);
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
Headers headers = response.headers();
Set<String> names = headers.names();
for (String name : names) {
Log.e(TAG, "请求的header" + name);
String value = headers.get(name);
Log.e(TAG, "值为: " + value + "\n----------------------------------");
}
final String date = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
mTvShow.setText(date);
}
});
}
});
以上步骤就能正常请求相应的数据了,如果还没有数据的话,好好看看代码!
1.2 简单的POST请求
关于POST请求的话,基本上就是比GET请求多一步设置表单的方法,也就是一个FormBody对象的设置,以key、value的方式设置表单而已,所以这里教你怎么写,然后我贴一下代码就那么滴了,谁让我那么懒呢!!!
表单的写法是这样的:
FormBody formBody = new FormBody.Builder()
.add("key", "value")
.build();
其实add方法可以被调用多次,添加相应的key和value;
整体的代码是这样的!!!
/*1.创建OkHttpClient对象*/
OkHttpClient httpClient = new OkHttpClient();
/*2.创建相应的表单内容*/
FormBody formBody = new FormBody.Builder()
.add("key", "value")
.build();
/*3.创建请求Request内容*/
Request request = new Request.Builder()
.url("https://www.baidu.com/")
.post(formBody)
.build();
/*4.发送请求*/
Call call = httpClient.newCall(request);
/*5.创建请求的回调*/
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "请求失败的原因:" + e);
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
Headers headers = response.headers();
Set<String> names = headers.names();
for (String name : names) {
Log.e(TAG, "请求的header" + name);
String value = headers.get(name);
Log.e(TAG, "值为: " + value + "\n----------------------------------");
}
final String date = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
mTvShow.setText(date);
}
});
}
});
}
POST和GET请求只是请求的方式不同,POST比较安全,所有内容都依靠表单传递!
2. OkHttp3进行文件上传
在这里先来个重要的说明:去写SD卡的权限一定要加,一定要加!!!
说到文件上传,一般的网络请求都带有文件上传的功能,其实OkHttp3也可以上传文件,具体操作步骤如下:
- 创建OkHttpClient对象
- 创建请求Request内容和所有所需参数(这里和其他的请求不同的地方)
- 获取文件
- 设置上传文件的类型
- 获取请求体
- 创建请求
- 创建请求的回调
因为其他的内容都差不多,只有关于表单的内容不通,所以这里着重讲一下关于这个表单的问题。
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "张三")
.addFormDataPart("image", "zhangsan.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), new File(Environment.getExternalStorageDirectory().getParent() + "/0/123.png")))
.build();
一般这种上传文件,基本上都是传递相应的用户图片,修改图片什么的!因为服务器要根据你上传的这张图片进行相应图片的替换。回来说上面那个配置:
- 上面第一个"title"那个参数的话,应该是一组key、value形式,基本上是根据服务器定的参数为准,可以有多组!
- 第二个"image"那个参数的话,基本上就是这个形式的key、图片名称、图片位置。这样就能锁定一张图片了,这样就构建出一个相应的RequestBody对象了。
整体代码是这样的:
/*1.创建OkHttpClient对象*/
OkHttpClient httpClient = new OkHttpClient();
/*2.创建相应的表单内容*/
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "张三")
.addFormDataPart("image", "zhangsan.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), new File(Environment.getExternalStorageDirectory().getParent() + "/0/123.png")))
.build();
/*3.创建请求Request内容*/
Request request = new Request.Builder()
.header("key", "value")
.url("https://www.baidu.com/")
.post(requestBody)
.build();
/*4.发送请求*/
Call call = httpClient.newCall(request);
/*5.创建请求的回调*/
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e(TAG, "onFailure: " + e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e(TAG, "onResponse: " + response.body().string());
}
});
对了忘说了一点,图片是以流的形式进行传递的。所以上面"application/octet-stream"配置的是这种格式,如果是其他的格式呢?给大家一份对照表:参照一下就OK了。
参数 | 说明 |
---|---|
text/html | HTML格式 |
text/plain | 纯文本格式 |
text/xml | XML格式 |
image/gif | gif图片格式 |
image/jpeg | jpg图片格式 |
image/png | png图片格式 |
application/xhtml+xml | XHTML格式 |
application/xml | XML数据格式 |
application/atom+xml | Atom XML聚合格式 |
application/json | JSON数据格式 |
application/pdf | pdf格式 |
application/msword | Word文档格式 |
application/octet-stream | 二进制流数据 |
基本上你把上面的代码改吧改吧就能上传文件了!!!就酱紫简单。。。
3. OkHttp的高端配置
3.1 OkHttp一些基本参数的配置
配置请求时间和连接超时的时间等等
OkHttpClient httpClient = new OkHttpClient.Builder()
//设置相应的连接池
.connectionPool(new ConnectionPool())
//连接超时
.connectTimeout(15, TimeUnit.SECONDS)
//写入超时
.writeTimeout(15, TimeUnit.SECONDS)
//读取超时
.readTimeout(20, TimeUnit.SECONDS)
.build();
3.2 OkHttp拦截器的一些简单理解
往往在项目中,都会有一些关于公共请求参数的一些问题,这里就会用到相应的OkHttp拦截器!什么是拦截器呢?简单点说就和埋点差不多。在请求的时候,会走每一个拦截器!想添加什么就添加什么,这里我们通过几个实例讲解一下你就能大概理解了!
3.2.1 日志拦截器
先看下代码,然后我在做一下相应的解释:
public class LogInterceptor implements Interceptor {
private static final String TAG = LogInterceptor.class.getSimpleName();
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
/*这样就能在请求之前打印相应的内容了*/
Log.e("url", String.format("Sending request %s on %s %n %s", request.url(), chain.connection(), request.headers()));
/*其实下面这个chain.proceed(request)这个方法,代表请求前和请求后*/
return chain.proceed(request);
}
}
这里就是直接打印了一个相应的LOG,可以获取到一些请求的参数,这里说明一下:
- 当你的请求为GET请求的时候只能打印一个Url地址,也就是
request.url()
的值了,饮后后面的headers获取到的内容为空,因为GET请求没有相应的表单信息; chain.connection()
当你使用除了日志拦截器的时候,就会返回空chain.proceed(request)
代表请求响应的结果,所以说明你也是可以修改返回结果的!!!
3.2.2 重定向一个网址链接的拦截器
这个说来就有意思了,当你请求拦截器的时候,正常应该返回百度返回的内容,但是如果你修改了链接的地址会怎么样呢?当然就会返回你修改之后的返回地址了。。。我们看看怎么实现的
最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
节跳动等公司2019-2021年的高频面试题**,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
[外链图片转存中…(img-MijAkiGO-1630583502199)]
【Android高级架构视频学习资源】