开源框架(三) : Retrofit源码分析
开源框架(三) : Retrofit
Retrofit是一个Restfusl 的 HTTP请求框架的封装, 网络请求的本质仍旧是OKHttp 完成的, retrofit 只是帮使用者进行工作简化, 比如配置网络,处理数据工作,提供复用性。
1. 基本使用
1.1 OKHTTP
OkHttpClient client = new OkHttpClient();
Requset request = new Request.Builder()
.url("Https://www.google.com").builder();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call Response reponse) {
}
});
}
OkHttp 的问题 :
- 用户网络请求的接口配置繁琐,尤其需要配置请求body, 请求头, 参数
- 数据解析过程需要用户手动拿到responsbody进行解析, 不能复用
- 无法适配自动进行线程切换
1.2 Retrofit
-
创建 Retrofit 实例
构建网络请求的载体对象, 和 OKhttp构建的OKHttpClent对象有一样的意义, 只不过Retrofot在build的时候有非常多的初始化内容,这些内容可以位后面网络请求准备,如Gson convert, RxjavaCallAdapter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Config.baseUrl)
//增加返回值为Gson的支持(以实体类返回)
.addConverterFactory(GsonConverterFactory.create())
.build();
- 创建model
public class UserModel {
private int code;
private String msg;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
- 创建service
public interface UserService {
@GET("boss/user/validlogin")
Call<UserModel> loginGet (@Query("username") String username, @Query("password") String password);
@POST("boss/user/validlogin")
@FormUrlEncoded
Call<UserModel> loginPost (@Field("username") String username, @Field("password") String password);
}
-
具体调用(同步)
Retrofit 精髓 位统一的配置网络请求完成动态代理的设置
private void getMethod(){
UserService service=RetrofitUtils.getInstance().getRetrofit().create(UserService.class);
Call<UserModel>call=service.loginGet(username,password);
// 同步调用
new Thread(new Runnable() {
@Override
public void run() {
try {
Response<UserModel>response=call.execute();
Log.e(TAG, "run: get同步请求 "+ "code --- > "+response.body().getCode()+"msg --- >"+response.body().getMsg());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
-
异步调用
构建具体的网络请求对象Request(Service),
-
将接口中的注释翻译成对应参数
-
确定网络请求接口的返回值(reponse)类型及对应的转换器
根据Service的Interface 来封装OKHttp的Requset
-
UserService service=RetrofitUtils.getInstance().getRetrofit().create(UserService.class);
Call<UserModel>call=service.loginGet(username,password);
//异步调用
call.enqueue(new Callback<UserModel>() {
@Override
public void onResponse(Call<UserModel> call, Response<UserModel> response) {
Log.e(TAG, "onResponse: get异步请求 "+"code --- > "+
response.body().getCode()+"msg --- >"+response.body().getMsg() );
}
@Override
public void onFailure(Call<UserModel> call, Throwable t) {
}
});
- 拿到结果
response.body().getCode()
response.body().getMsg());
2. 两者区别
- OKHttp 创建的是 OKHTTPClient, 然而 Retrofit 创建的是 Retrofit 实力
- OKHttp 手动配置 Request, Retroft通过注解配置
- Retroft 是利用Adapter适配OKHttp的Call
- Retrofit 会对 ReponseBody 进行自动的Gson解析
- 相对OkHttp, Retrofit 会自动的完成线程切换
3. 封装实现
最重要的两个类
- Retrofit
- ServiceMethod
3.1 Retrofit 构建过程
Retrofit 通过构建者模式生成Retrogit对象, 默认是OKHttp来发送网络请求,也可以自己定制
更改构一个Retrofit对象的标准: 配置好Retrofit类里的成员变量
- baseUrl 网络请求Url
- callFactory 网络请求工厂
- callbackExecutor 回调方法执行器
- adapterFactories 网络请求适配器工厂集合
- converterFactories 数据转换器工厂集合
-
初始化 构建Call 工厂, 直接使用了 OkHttpCall,目的就是构建一个OKHttpClient 换句话说,这里调用就是产生了OKHttp网络请求需要的请求Call。
-
网络请求需要子线程总进行, 需要线程管理,这个地方就是运用Handler进行线程切换, 主线程的Handler
-
defaultCallAdapterFactory 此出属于系统默认的, 也可以在添加RxJavaCallAdapterFactory , 完成Retrofit 对 OKHttp的封装。
-
convertFactories 数据转换器工厂
3.2 Retrofit 构建 IxxService对象的过程(Retrofit.creat())
在Create里面使用了动态代理的技术方案, 让所有的访问请求都被代理。
网络请求不边的是 URL, 配置
变得是 请求参数 请求方法
将网络接口的参数配置归一化
service=RetrofitUtils.getInstance().getRetrofit().create(UserService.class);
Call<UserModel>call=service.loginGet(username,password);
- 根据方法生成一个ServiceMethod对象。
- 根据ServiceMethod对象和请求参数生成一个OKHTTP对象,发起网络请求
- 调用ServiceMethod的callAdapter的 adapter方法,并传入okHttpcall,返回一个对象,这个的目的主要是为了适配返回类型,器内部会对OKHttpCall对象进行包装,生成对应的返回类型的对象。方法的返回参数是Call对象, 那么ServoceMethod就会默认的CallAdapterFactory来生成CallAdapter,返回的RXJava的Obserable对象,则会使用RxJavaCallAdapterFactory提供的CallAdapter。
缓存 ServiceMethod, ServiceMethod 其实是用来存一次网络请求的基本信息, 比如Host, URL ,请求方法。
参数适配(重要):
result = new ServiceMethod.Builder(this, method).build();
将网络请求的核心类 OKHTTPCall进行适配,需要什么类型的数据就通过适配器进行适配,返回适配后的对象就是了,正式这种CallAdapter接口的设计,使用Retrofit的时候可以定义我们想要的返回类型。
设计模式
- Retrofit 实例使用建造者设计模式通过类构建, 当构造函数的参数大于四个,且存在可选参数的时候可以使用建造者设计模式
- Retrofit 创建的时的callFactroy使用方法工厂设计模式
- 整个Retrofit 采用外观模式 , 统一调用创建网络请求结论实例和网络请求参数配置的方法
- retrofit 里面使用了动态代理来创建网络请求接口实例,
- 使用了策略模式对ServiceMethod对象进行网络请求参数配置,即通过解析网络请求接口方法的参数,返回值和注解类型,从Retrofit对象中获取对应的网络的url地址,网络请求执行器 网络请求适配器和数据转换器
总结:
Retrofit 主要面向开发者, 方便使用做了应用层的封装,响应数据的处理,错误处理, 线程转换,数据转换。
RxJava + Retrofit + OKHttp 框架, Retrofit 负责请求数据和请求结果,使用接口的方式呈现,OKHttp负责请求的过程,RxJava负责异步线程切换。