目录
1 什么是OKHttp
1.1 网络请求发展
历史上Http请求库优缺点
在讲述OKHttp之前, 我们看下没有OKHttp的时代, 我们是如何完成http请求的 在没有OKHttp的日子, 我们使用 HttpURLConnection 或者 HttpClient . 那么这两者都有什么优缺点 呢? 为什么不在继续使用下去呢? HttpClient 是Apache基金会的一个开源网络库, 功能十分强大, API数量众多, 但是正是由于庞大的API
数量使得我们很难在不破坏兼容性的情况下对它进行升级和扩展, 所以Android团队在提升和优化
HttpClient方面的工作态度并不积极。
HttpURLConnection 是一种多用途, 轻量极的HTTP客户端, 提供的API比较简单, 可以容易地去使用和 扩展. 不过在Android 2.2版本之前, HttpURLConnection 一直存在着一些令人厌烦的bug. 比如说对一个 可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是 直接禁用掉连接池的功能:
private void disableConnectionReuseIfNecessary() {
// 这是一个2.2版本之前的bug
if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
System.setProperty("http.keepAlive", "false");
}
}
因此,一般的推荐是在2.2之前, 使用 HttpClient , 因为其bug较少. 在2.2之后, 推荐使用
HttpURLConnection , 因为API简单, 体积小, 并且有压缩和缓存机制, 并且Android团队后续会继续优化
HttpURLConnection .
但是, 上面两个类库和 OKHttp 比起来就弱爆了, 因为OKHttp不仅具有高效的请求效率, 并且提供了很多 开箱即用的网络疑难杂症解决方案.
支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上 一次性发送多个请求来发送或接收数据 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时 支持GZIP, 可以压缩下载体积 响应缓存可以直接避免重复请求 会从很多常用的连接问题中自动恢复 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OKHttp会自动尝试下一个IP OKHttp还处理了代理服务器问题和SSL握手失败问题
使用 OKHttp 无需重写您程序中的网络代码。OKHttp实现了几乎和java.net.HttpURLConnection一样的API。如果你用了 Apache HttpClient,则OKHttp也提供了一个对应的OKHttp-apache 模块。
1.2OKHttp是什么
OKHttp是一个网络请求开源项目,Android网络请求轻量级框架,支持文件上传与下载,支持https。
2 OKHttp的作用
2.1 OKHttp是一个高效的HTTP库:
支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上 一次性发送多个请求来发送或接收数据 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时 支持GZIP, 可以压缩下载体积 响应缓存可以直接避免重复请求 会从很多常用的连接问题中自动恢复 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OKHttp会自动尝试下一个IP OKHttp还处理了代理服务器问题和SSL握手失败问题
2.2 优势
使用 OKHttp无需重写您程序中的网络代码。OKHttp实现了几乎和java.net.HttpURLConnection一样的API。如果您用了 Apache HttpClient,则OKHttp也提供了一个对应的OKHttp-apache 模块
3 OKHttp的作用
OKHttp的基本使用,从以下五方面讲解:
1. Get请求(同步和异步)
2. POST请求表单(key-value)
3. POST请求提交(JSON/String/文件等)
4. 文件下载
5. 请求超时设置
加入build.gradle
implementation("com.squareup.okhttp3:okhttp:4.10.0")
3.1发送请求
3.1.1Get请求(同步/异步)
同步:
第一步:添加依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
第二步:设置网络权限
<uses-permission android:name="android.permission.INTERNET" />
第三步:进行网络请求
1. 创建线程
2. 创建客户端
3. 创建请求
4. 使用客户端发送请求
5. 处理返回结果
new Thread(new Runnable() {
@Override
public void run() {
//创建客户端
OkHttpClient client = new OkHttpClient();
//创建请求
Request request = new Request.Builder()
.url("https://api.vvhan.com/api/mobil.girl?type=json")
.build();
//使用客户端发送请求
try (Response response = client.newCall(request).execute()) {
result = response.body().string();
handler.sendEmptyMessage(0x111);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
}
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 0x111) {
try {
JSONObject object = new JSONObject(result);
String imgurl = object.getString("imgurl");
Glide.with(MainActivity.this).load(imgurl).into(im_show);
} catch (JSONException e) {
e.printStackTrace();
}
}
第四步:Handler
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what == 0x111) {
try {
JSONObject object = new JSONObject(result);
String imgurl = object.getString("imgurl");
Glide.with(MainActivity.this).load(imgurl).into(iv_show);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
};
异步:
第一步:添加依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
第二步:设置网络权限
<uses-permission android:name="android.permission.INTERNET" />
第三步:进行网络请求
1. 创建线程
2. 创建客户端
3. 创建请求
4. 使用客户端发送请求
5. 处理返回结果
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.vvhan.com/api/mobil.girl?type=json")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.i("nofailure", "fail");
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
result = response.body().string();
handler.sendEmptyMessage(0x111);
Log.i("onResponse", result);
}
});
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 0x111) {
try {
JSONObject object = new JSONObject(result);
String imgurl = object.getString("imgurl");
Glide.with(MainActivity.this).load(imgurl).into(im_show);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
第四步:Handler
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what == 0x111) {
try {
JSONObject object = new JSONObject(result);
String imgurl = object.getString("imgurl");
Glide.with(MainActivity.this).load(imgurl).into(iv_show);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
};
3.1.2Post请求(同步/异步)
同步:
第一步:添加依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
第二步:设置网络权限
<uses-permission android:name="android.permission.INTERNET" />
第三步:进行网络请求
1. 创建线程
2. 创建客户端
3. 创建请求体,将参数放到请求体当中
4.创建请求
5. 使用客户端发送请求
6. 处理返回结果
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
MediaType mediaType =
MediaType.Companion.parse("application/json;charset=utf-8");
MediaType param = null;
RequestBody stringBody = RequestBody.Companion.create(String.valueOf(param), mediaType);
Request request = new Request.Builder()
.url("http://192.168.17.181:8080/TestWeb_war_exploded/login")
.post(stringBody)
.build();
try (Response response = client.newCall(request).execute()) {
result = response.body().string();
handler.sendEmptyMessage(0x111);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
}
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 0x111) {
Toast.makeText(MainActivity2.this, result, Toast.LENGTH_LONG).show();
}
}
第四步:Handler
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 0x111) {
Toast.makeText(LoginActivity.this, result,
Toast.LENGTH_SHORT).show();
}
}
};
异步:
第一步:添加依赖
implementation("com.squareup.okhttp3:okhttp:4.10.0")
第二步:设置网络权限
<uses-permission android:name="android.permission.INTERNET" />
第三步:进行网络请求
1. 创建线程
2. 创建客户端
3. 创建请求体,将参数放到请求体当中
4.创建请求
5. 使用客户端发送请求
6. 处理返回结果
8OkHttpClient okHttpClient = new OkHttpClient();
MediaType type = MediaType.Companion.parse("application/json;charset=utf-8");
MediaType param = null;
RequestBody requestBody = RequestBody.Companion.create(String.valueOf(param), type);
Request request = new Request.Builder()
.url("http://192.168.17.181:8080/TestWeb_war_exploded/login")
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
Log.e("onFailure", "fail");
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
result = response.body().string();
handler.sendEmptyMessage(0x111);
}
});
}
第四步:Handler
private Handler handler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==0x111) {
Toast.makeText(MainActivity2.this, result, Toast.LENGTH_SHORT).show();
}
}
};
3.2同步和异步的小结
1. 同步需要开启线程,异步不需要开启线程
2. 同步和异步都需要跳转到UI线程修改UI