网络框架学习(OkHttp与Retrofit框架)
1.OKHttp基本用法
-
首先导入依赖,在build.gradle文件中
implementation("com.squareup.okhttp3:okhttp:4.9.0")
-
然后在AndroidMainfest.xml文件中设置网络权限
<uses-permission android:name="android.permission.INTERNET"/>
1.OkHttp框架的get方式同步请求
//get的同步请求
public void getSync(View view){
new Thread(){
@Override
public void run() {
Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
Call call = okHttpClient.newCall(request);
try {
//execute方法会阻塞后续代码的执行
Response response = call.execute();
Log.i("lod",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
需要注意的是,get方式同步请求必须在线程中使用!
2.get方式异步请求
public void getAsync(View view) {
Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2")
.build();
// 准备好请求的Call对象
Call call = okHttpClient.newCall(request);
//异步请求
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
//请求失败的回调
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//如果是成功的
if (response.isSuccessful()) {
Log.i("log", "getAsync: " + response.body().string());
}
}
});
}
同步请求用的是Call对象的execute()方法来发送请求并获取服务器返回的数据,异步请求用的是enqueue()方法
3.post方式同步请求
//post方式进行同步请求
public void postSync(View view) {
new Thread() {
@Override
public void run() {
FormBody formBody = new FormBody.Builder()
.add("a", "1").add("b", "2").build();
Request request = new Request.Builder().url("https://www.httpbin.org/post")
.post(formBody).build();
// 准备好请求的Call对象
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
Log.i("log", "postSync: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
还是需要注意同步请求方式都需要线程来处理!
Respose产生的对象作为一个回调对象,在服务器响应之后就会回调结果到前端。
4.post方式异步请求
//post方式异步请求
public void postAsync(View view) {
FormBody formBody = new FormBody.Builder()
.add("a", "1").add("b", "2").build();
Request request = new Request.Builder().url("https://www.httpbin.org/post")
.post(formBody).build();
// 准备好请求的Call对象
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
Log.i("log", "postAsync: " + response.body().string());
}
});
}
用FormBody表单形式来进行异步请求处理。
注意异步请求添加参数的方式,用add()方法添加,可对比get方式直接在URL中添加参数。
5.OkHttp框架拦截器
@Test
public void interceptorTest() {
/*
Cache是缓存类,只要有请求就会自动判断是否满足缓存的条件(这里自己定义了缓存容量最大不能超过1M),
如果没超过,就会自动读取在上次网络请求中缓存到本地的数据,如果超过,则删除缓存,再次发起请求建立连接缓存新数据。
*/
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cache(new Cache(new File("C:\\Users\\Administrator\\Desktop"),
1024 * 1024)).addNetworkInterceptor(new Interceptor() {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
System.out.println("version:" + chain.request().header("version"));
return chain.proceed(chain.request());
}
}).addInterceptor(new Interceptor() {
@NotNull
@Override
/*
所有的请求都会经过拦截器,这样就可以不用单独的在每一个请求上面添加请求头、服务器的版本号等,
减少了工作量和代码的冗余度
*/
public Response intercept(@NotNull Chain chain) throws IOException {
//前置处理
//得到服务器的版本号、请求头
Request request = chain.request().newBuilder().addHeader("os", "android")
.addHeader("version", "1.0").build();
//发出得到的request
Response response = chain.proceed(request);
//后置处理
return response;
}
}).build();
Request request = new Request.Builder().url("https://www.httpbin.org/get?a=1&b=2").build();
// 准备好请求的Call对象
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
Cache是缓存类,只要有请求就会自动判断是否满足缓存的条件(这里自己定义了缓存容量最大不能超过1M),
如果没超过,就会自动读取在上次网络请求中缓存到本地的数据,如果超过,则删除缓存,再次发起请求建立连接缓存新数据。
6.缓存与Cookie
public class CookieUnitTest {
Map<String, List<Cookie>> cookies = new HashMap<>();
@Test
public void cookieTest() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(new CookieJar() {
@Override
public void saveFromResponse(@NotNull HttpUrl httpUrl, @NotNull List<Cookie> list) {
cookies.put(httpUrl.host(), list);
}
@NotNull
@Override
public List<Cookie> loadForRequest(@NotNull HttpUrl httpUrl) {
List<Cookie> cookies = CookieUnitTest.this.cookies.get(httpUrl.host());
// List<Cookie> cookies1 = cookies == null ? (List<Cookie>) new ArrayList<>() : cookies;
return cookies;
}
})
.build();
FormBody formBody = new FormBody.Builder().add("username", "lanceedu")
.add("password", "123123").build();
Request request = new Request.Builder().url("https://www.wanandroid.com/user/login")
.post(formBody).build();
// 准备好请求的Call对象
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
request = new Request.Builder().url("https://www.wanandroid.com/lg/collect/list/0/json")
.build();
// 准备好请求的Call对象
call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Cookie是某些网站为了辨别用户身份,进行会话跟踪(比如确定登陆状态)而储存在用户本地终端上的数据(通常经过加密),
由用户客户端计算机暂时或永久保存的信息
2.Retrofit框架的使用
Retrofit封装了OkHttp,是一个处理网络请求的开源项目。
1.根据Http接口来创建java接口
public interface HttpbinService {
@POST("post")
@FormUrlEncoded
//如果是post请求,则传参过程需要Field注解
Call<ResponseBody> post(@Field("username") String userName, @Field("password") String pwd);
@GET("get")
//如果是get请求,则传参过程需要Query注解
Call<ResponseBody> get(@Query("username") String userName, @Query("password") String pwd);
}
2.创建Retrofit对象,并生成接口实现类对象;
retrofit = new Retrofit.Builder().baseUrl("https://www.httpbin.org/").build();
httpbinService = retrofit.create(HttpbinService.class);
3.接口实现类对象调用对应方法获得相应
retrofit2.Call<ResponseBody> call = httpbinService.post("lance", "123");
call.enqueue(new retrofit2.Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
Log.i(TAG, "postAsync: " + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
}
});
调用接口就可以实现post、get请求
安卓29以上由于保护机制,不允许直接使用http协议,只允许使用HTTPS协议,解决办法:
在mainfests中添加如下代码:
android:cleartextTrafficPermitted=“true”