1. 导包
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
2. 权限配置
为了保证数据安全,Google从Anroid 9开始要求禁止所有的未加密数据请求,也就是说,Android 9以上将不能直接使用http请求数据,但是依然保留了相关的开关设置。所以本文的例子中,除了配置传统的网络权限之外,还要多做些配置,使高版本的机器上也能正常使用http。具体配置如下:
在res-xml文件夹下创建network_config.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" overridePins="true" />
<certificates src="user" overridePins="true" />
</trust-anchors>
</base-config>
</network-security-config>
Manifest.xml添加属性:
android:networkSecurityConfig="@xml/network_config"
network_config.xml配置文件的作用就是允许用户使用http进行明文通讯,只不过在Android 9以上系统默认禁止了。
3. 不带参数get请求
在请求数据之前我们先配置一下本地服务,github上搜索SOBAndroidMiniWeb,按照文档提示启动本地服务,然后创建不带参数的请求,请求地址是:本机ip:9102/get/text。 我们先用postman请求到接口数据,然后把接口返回的json数据转换成Java类。下面是请求和接收的过程:
//创建OkHttpClient,设置超时时长
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3000, TimeUnit.MILLISECONDS).build();
//创建一个get请求
Request request = new Request.Builder().get().url("http://192.168.2.8:9102/get/text").build();
//发送get请求
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e(TAG,"ERROR");
Looper.prepare();
tv_content.setText("error");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String resp = response.body().string();
Gson gson = new Gson();
MyResponse myResponse=gson.fromJson(resp,MyResponse.class);
// Log.e(TAG,myResponse.getName());
Looper.prepare();
tv_content.setText(myResponse.getData()[0].getTitle());
}
4. 带参数get请求
带参数的接口请求地址使用本机ip:9102/get/param,带参数的get请求与不带参数的get请求在配置上没有什么区别,唯一的区别就是带参数的请求需要在url上拼接参数,参数的格式一般为:baseurl?key=value&key=value...,下面是具体的请求过程:
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3000,TimeUnit.MILLISECONDS).build();
//拼接参数
Map<String,String> params = new HashMap<>();
params.put("keyword","hello");
params.put("page","1");
params.put("order","0");
StringBuilder builder = new StringBuilder();
Iterator<Map.Entry<String,String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String,String> next = iterator.next();
String key = next.getKey();
String value = next.getValue();
builder.append(key);
builder.append("=");
builder.append(value);
if (iterator.hasNext()){
builder.append("&");
}
}
//拼接URL
String url = "http://192.168.2.8:9102/get/param?"+builder.toString();
Request request = new Request.Builder().get().url(url).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e(TAG,"ERROR");
Looper.prepare();
tv_content.setText("error");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String resp = response.body().string();
Gson gson = new Gson();
MyResponseNoParam myResponse=gson.fromJson(resp,MyResponseNoParam.class);
// Log.e(TAG,myResponse.getName());
Looper.prepare();
tv_content.setText(myResponse.getMessage());
}
});
}
5. post请求
我们通过提交一个字符串来模拟post请求,post请求的过程中需要构建一个requestbody,并且指定MediaType的类型,由于我们开发过程中使用的数据格式大部分是json类型的,所以MediaType也指定为json类型的。具体请求过程如下:
//创建OkHttpClient,设置超时时长
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3000, TimeUnit.MILLISECONDS).build();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name","hello");
RequestBody body = RequestBody.create(jsonObject.toString(),MediaType.parse("application/json"));
//创建一个get请求
Request request = new Request.Builder().post(body).url("http://192.168.2.8:9102/post/string?string=name").build();
//发送get请求
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e(TAG,"ERROR");
Looper.prepare();
tv_content.setText("error");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String resp = response.body().string();
Gson gson = new Gson();
MyResponseNoParam myResponse=gson.fromJson(resp,MyResponseNoParam.class);
// Log.e(TAG,myResponse.getName());
Looper.prepare();
tv_content.setText(myResponse.getMessage());
}
});
这一小结先记录一下OKhttp的get和post请求,下一小节记录文件的上传和下载。
记录码农生活,做一个快乐的coder