一:认识Retrofit和okhttp3
Retrofit是由square 开发设计的 网络请求框架
官方网址:Retrofit
Okhttp 是由square 开发设计的 网络请求库,请求/响应API采用流畅的构建器和不变性设计。它同时支持同步阻塞调用和带有回调的异步调用
官方网址:Overview - OkHttp
这篇博客是网络请求的基础篇,使用Retrofit作为网络请求及响应的载体,了解Retrofit的注解,Okhttp的作用在于日志过滤,以及完善网络请求(比如超时处理,请求体处理等)
使用方法如下:
在app\build.gradle
1:依赖Maven库
dependencies {
//retrofit2 okhttp3
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"
}
2:jar包依赖
在官网下载
二:准备工作
免费的Json数据接口 :
1:构造Retrofit对象
//构造retrofit,返回请求接口
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(builder.build())
.build();
service = retrofit.create(BaseService.class);
2:添加okhttp日志过滤器
//构造okhttp3,日志过滤
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT);
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if(BuildConfig.DEBUG){
builder.addInterceptor(interceptor);
}
3:构建CallBack
//构建Callback
public void callEnqueue(Call<T> call,BaseListener<T> listener){
call.enqueue(new Callback<T>() {
@Override
public void onResponse(@NonNull Call<T> call, @NonNull Response<T> response) {
if(response.isSuccessful()){
listener.onResponse(response.body());
}else{
listener.onFail(response.message());
}
}
@Override
public void onFailure(@NonNull Call<T> call, @NonNull Throwable t) {
listener.onFail(t.getMessage());
}
});
}
4:完善Service请求接口,了解各注解作用
//方法注解:@GET @POST @PUT @DELETE @PATH @HEAD @OPTIONS @HTTP // //标记注解:@FormUrlEncoded @Multipart @Streaming // //参数注解:@Query @QueryMap @Body @Field @FieldMap @Part @PartMap // //其他注解:@Path @Header @Headers @Url
以GET/POST/包含请求头Headers,路径参数,请求参数,Json数据,文件参数为例
//路径参数
@GET("posts/{postId}/comments")
Call<List<CommentsBean>> getComments(
@Path("postId") int postId
);
@GET("photos")
Call<List<PhotoBean>> getPhoto(
@Query("id") int id
);
//请求参数
@GET("users")
Call<List<UserBean>> getUser(
@Query("id") int id);
//Post请求
@POST("todos")
Call<TodoBean>postTodo();
//包含请求头的POST请求
@Headers("Content-Type:application/x-www-form-urlencoded")
@POST("api/sdk/stat/v1/launch/{gameId}/{channelId}")
Call<StatsBean>postLaunchGame(
@Path("gameId") String gameId,
@Path("channelId") String channelId,
@Body RequestBody responseBody
);
//包含json的POST请求
//上传跑步数据
@FormUrlEncoded
@POST("Record/uploadRunningRecord")
Call<BaseBean> uploadRunningRecord(@Field("Json") String route);
//上传跑步地图截屏
@Multipart
@POST("Record/uploadRunningImage")
Call<BaseBean> uploadRunningImage(@Part MultipartBody.Part file,
@Query("sessionId") String sessionId,
@Query("studentId") String studentId);
5:发起请求,调用实例
private void getPhoto(ImageView imageView) {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("正在加载中...");
dialog.show();
BaseModel<List<PhotoBean>> model = new BaseModel<>();
Call<List<PhotoBean>> call = model.service.getPhoto(3);
model.callEnqueue(call, new BaseListener<List<PhotoBean>>() {
@Override
public void onResponse(List<PhotoBean> bean) {
dialog.dismiss();
Glide.with(MainActivity.this).load(bean.get(0).getUrl())
.placeholder(R.drawable.ic_launcher_background)
.into(imageView);
}
@Override
public void onFail(String e) {
dialog.dismiss();
Log.d(TAG, "getPhoto onFail:" + e);
}
});
}
Retrofit的onResponse和onFail是在主线程的,已经完成了线程切换,可以进行UI操作。
这是与Okhttp的区别。
6:效果图
附上完整demo:
GitHub - sunbofly23/JavaRetrofitOkhttp: retrofit+okhttp,安卓网络请求框架
三:从源码分析:
基于retrofit:2.9.0
下面简单梳理了一下retrofit 使用的技术点
retrofit:构建者设计模式,工厂模式,反射,动态代理,类加载器,注解
这里先过一遍retrofit从构建,到与okhttp转换的流程:
Retrofit.
->create(Retrofit.java)
->invokeHandle(Retrofit.java)
->loadServiceMethod-一层缓存(serviceMethodCache)(ServiceMethod.java)
->createCallAdapter(HttpServiceMethod.java)
->createResponseConverter(HttpServiceMethod.java)
->invoke(HttpServiceMethod.java)
->构造OkHttpCall并且adapt(call) 这一步结束,就是将Call交给okhttp发起请求
->get(CallAdapter<R, T> .Factory.java)
->DefaultCallAdapterFactory(DefaultCallAdapterFactory extends CallAdapter.Factory)
->ExecutorCallbackCall(DefaultCallAdapterFactory.java)这一步完成线程的切换
->CompletableFutureCallAdapterFactory(CompletableFutureCallAdapterFactory extends CallAdapter.Factory)
->retrun future(CompletableFuture)
然后从Retrofit.create开始分析
->loadServiceMethod
->createCallAdapter、createResponseConverter
->invoke
->DefaultCallAdapterFactory
->ExecutorCallbackCall
这里就会将请求 进队列交给okhttp3
->CompletableFutureCallAdapterFactory
->retrun future/callback.onResponse解析response.body()
四:总结
复盘网路请求Retrofit+okhttp的简单使用,据了解,最新技术
Retrofit+okhttp+moshi+kotlin协程
可实现的网络请求框架更易扩展,健壮。后续还要学习。