一、Android 网络库的发展
Google在Android4.4以后开始将源码中的 HttpuRLconnection 底层实现替换为 oKHttp,同时现在流行的 Retrofit 框架底层同样是使用oKHttp。
二、★ OkHttp
gitHub: GitHub - square/okhttp
使用帮助文档:OkHttp 3.14.0 API
(一)出现背景
网络访问的高效性要求,为高效而生
(二)定义与作用
OkHttp是一个适用于Android和Java应用程序(支持Android 2.3及以上、Java最低1.7版本)、默认高效的HTTP和HTTP/2客户端,由Square公司提供的开源网络请求框架。
作用:通过建造者模式(Builder Pattern),完成复杂的网络请求
建造者模式属于设计模式三大类型中创建型
(三)高级功能
- 支持HTTP/2:支持允许对同一主机的所有请求共享一个套接字
- 连接池:重用 HTTP 和 HTTPS 连接,减少了请求延迟和 TCP 连接开销
- 透明GZIP:缩小了下载大小,减少网络传输数据量
- 响应缓存:完全避免了重复请求的网络,提高访问速度
- 请求重试:在连接失败时,自动重试一个主机的多个 IP 地址
- 在较高的层次上,客户端被设计用于阻止同步调用和非阻止异步调用
(四)OkHttp3设计思路
OkHttp3是OkHttp的最新版本,强烈建议跟随官网随时更新OkHttp
三、OkHttp使用
(一)添加依赖+网络权限
//build.grade(app)
//dependencies
implementation("com.squareup.okhttp3:okhttp:4.12.0")
<uses-permission android:name="android.permission.INTERNET"/>
测试URL (统一资源定位符):https://www.httpbin.org/ (后面会用到)
(二)使用演示
这里只演示 get 和 post, 建议将代码复制下来,认真看注释
- 同步请求:发出请求后,阻塞不能继续做任何事,请求返回后才能继续做事;
- 异步请求:发出请求后,可去做其他事,请求完成后,有回调,会通知你处理这个回应。
步骤
- new 客户端对象OkHttpClient
- new 请求对象 Request
- 生成 call对象, 发送登录请求到服务器
- call发起请求(同步/异步),得到回应 response
准备
如果运行出错,可以一直clean、rebuild一下项目试试
1.get 同步请求
private OkHttpClient okHttpClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.new客户端对象OkHttpClient
okHttpClient = new OkHttpClient();
}
//get 同步请求
public void get_sync(View view) {
//Android中网络请求必须启动一个子线程,在线程中完成请求
new Thread() {
@Override
public void run() {
super.run();
//2.new请求Request,构建url,并上传参数
Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
//3.生成Call请求对象
Call call = okHttpClient.newCall(request);
// 4.Call发起请求(同步/异步)
try {
Response response = call.execute();
//5
Log.i("coderSong", "get 同步请求" + response.body().string());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}.start();
}
2.get 异步请求
不需要我们启动子线程(enqueue本身会启动),可以在主线程中直接使用
//get 异步请求
public void get_async(View view) {
//2.new 请求
Request request = new Request.Builder().url("https://www.httpbin.org/get?c=3").build();
//3.call对象
Call call = okHttpClient.newCall(request);
//4.发起请求
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
//请求失败
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
//仅代表和服务器通信成功,不代表和https通信成功(比如可能返回404 Found)
if (response.isSuccessful()) {
Log.i("coderSong", "get 异步请求" + response.body().string());
}
}
});
}
1.请求默认是get的,如果要post,只需在后面加上.post
2.get请求参数加在?后面,post请求参数必须在单独的请求体中
3.post 同步请求
//post 同步请求
public void post_sync(View view) {
new Thread() {
@Override
public void run() {
super.run();
FormBody formBody = new FormBody.Builder().add("e", "1").add("f", "2").build();
//2.new请求Request,构建url,并上传参数
Request request = new Request.Builder()
.url("https://www.httpbin.org/post")
.post(formBody).build();
//3.生成Call请求对象
Call call = okHttpClient.newCall(request);
// 4.Call发起请求(同步/异步)
try {
Response response = call.execute();
//5
Log.i("coderSong", "post 同步请求" + response.body().string());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}.start();
}
4.post 异步请求
//post 异步请求
public void post_async(View view) {
FormBody formBody = new FormBody.Builder().add("g", "g").build();
//2.new 请求
Request request = new Request.Builder()
.url("https://www.httpbin.org/post")
.post(formBody)
.build();
//3.call对象
Call call = okHttpClient.newCall(request);
//4.发起请求
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
//请求失败
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
//仅代表和服务器通信成功,不代表和https通信成功(比如可能返回404 Found)
if (response.isSuccessful()) {
Log.i("coderSong", "post 异步请求" + response.body().string());
}
}
});
}