开源框架(三) : 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

  1. 创建 Retrofit 实例

    构建网络请求的载体对象, 和 OKhttp构建的OKHttpClent对象有一样的意义, 只不过Retrofot在build的时候有非常多的初始化内容,这些内容可以位后面网络请求准备,如Gson convert, RxjavaCallAdapter

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Config.baseUrl)
                //增加返回值为Gson的支持(以实体类返回)
              .addConverterFactory(GsonConverterFactory.create())
                .build();
  1. 创建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;
    }
}
  1. 创建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);
}
  1. 具体调用(同步)

    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();

    }
  1. 异步调用

    构建具体的网络请求对象Request(Service),

    1. 将接口中的注释翻译成对应参数

    2. 确定网络请求接口的返回值(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) {

            }
        });
  1. 拿到结果
response.body().getCode()
response.body().getMsg());

2. 两者区别

  1. OKHttp 创建的是 OKHTTPClient, 然而 Retrofit 创建的是 Retrofit 实力
  2. OKHttp 手动配置 Request, Retroft通过注解配置
  3. Retroft 是利用Adapter适配OKHttp的Call
  4. Retrofit 会对 ReponseBody 进行自动的Gson解析
  5. 相对OkHttp, Retrofit 会自动的完成线程切换

3. 封装实现

最重要的两个类

  • Retrofit
  • ServiceMethod

3.1 Retrofit 构建过程

Retrofit 通过构建者模式生成Retrogit对象, 默认是OKHttp来发送网络请求,也可以自己定制

更改构一个Retrofit对象的标准: 配置好Retrofit类里的成员变量

  • baseUrl 网络请求Url
  • callFactory 网络请求工厂
  • callbackExecutor 回调方法执行器
  • adapterFactories 网络请求适配器工厂集合
  • converterFactories 数据转换器工厂集合

  1. 初始化 构建Call 工厂, 直接使用了 OkHttpCall,目的就是构建一个OKHttpClient 换句话说,这里调用就是产生了OKHttp网络请求需要的请求Call。

  2. 网络请求需要子线程总进行, 需要线程管理,这个地方就是运用Handler进行线程切换, 主线程的Handler

    image-20220712160837158

  3. defaultCallAdapterFactory 此出属于系统默认的, 也可以在添加RxJavaCallAdapterFactory , 完成Retrofit 对 OKHttp的封装。

  4. convertFactories 数据转换器工厂

3.2 Retrofit 构建 IxxService对象的过程(Retrofit.creat())

在Create里面使用了动态代理的技术方案, 让所有的访问请求都被代理。

网络请求不边的是 URL, 配置

变得是 请求参数 请求方法

将网络接口的参数配置归一化

service=RetrofitUtils.getInstance().getRetrofit().create(UserService.class);
        Call<UserModel>call=service.loginGet(username,password);

  1. 根据方法生成一个ServiceMethod对象。
  2. 根据ServiceMethod对象和请求参数生成一个OKHTTP对象,发起网络请求
  3. 调用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的时候可以定义我们想要的返回类型。

设计模式

  1. Retrofit 实例使用建造者设计模式通过类构建, 当构造函数的参数大于四个,且存在可选参数的时候可以使用建造者设计模式
  2. Retrofit 创建的时的callFactroy使用方法工厂设计模式
  3. 整个Retrofit 采用外观模式 , 统一调用创建网络请求结论实例和网络请求参数配置的方法
  4. retrofit 里面使用了动态代理来创建网络请求接口实例,
  5. 使用了策略模式对ServiceMethod对象进行网络请求参数配置,即通过解析网络请求接口方法的参数,返回值和注解类型,从Retrofit对象中获取对应的网络的url地址,网络请求执行器 网络请求适配器和数据转换器

总结:

Retrofit 主要面向开发者, 方便使用做了应用层的封装,响应数据的处理,错误处理, 线程转换,数据转换。

RxJava + Retrofit + OKHttp 框架, Retrofit 负责请求数据和请求结果,使用接口的方式呈现,OKHttp负责请求的过程,RxJava负责异步线程切换。

posted @ 2022-06-11 21:58  AronJudge  阅读(173)  评论(0编辑  收藏  举报