Retrofit面试该说些什么

相信大家都用过Retrofit这个框架,但是面试官让你说说retrofit这个框架往往面试者不知道怎么回答,在这里我给大家提供一个思路。

1、基本的使用。
第一步、通过Retrofit的builder模式创建一个retrofit对象,可以在builder里面设置okhttpclient、baseurl、callAdapterFactroy、addConverterFactory等信息。
第二步、通过得到的retrofit对象加工要请求的接口,得到一个接口对象。
第三步、通过这个接口对象,调用接口里面的方法得到一个网络工作对象。
第四步、通过这个网络工作对象调用enqueue方法或者execute方法发起请求并且回调回请求的结果。具体代码如下:

     //1、通过builder方式创建一个retrofit对象,可以添加client baseurl addConverterFactory addCallAdapterFactory 等信息
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("")
                .addConverterFactory(null)
                .addCallAdapterFactory(null)
                .client(null)
                .build();
        //2、通过retrofit.create加工得到一个网络接口对象
        INetApiService iNetApiService = retrofit.create(INetApiService.class);
        //3、调用网络接口对象的接口函数,得到一个网络工作对象
        Call<Book> call = iNetApiService.getBook();
        //4、通过网络工作对象发起一个请求并回调回请求的结果
        call.enqueue(new Callback<Book>() {
            @Override
            public void onResponse(Call<Book> call, Response<Book> response) {

            }
            @Override
            public void onFailure(Call<Book> call, Throwable t) {
            }
        });

从上面的用法就可以看到,retrofit的存在不是它去请求对象,它的作用是生成帮助开发者生成网络请求对象的封装,和按照接口返回对应的网络工作对象,真正的网络请求发生在网络工作对象上的。

retrofit解决的问题:在以前做网络请求的时候,会考虑到如何封装请求数据,如何发起请求,到最后对返回数据的封装分类都需要开发人员自己维护,开发成本大不说,还容易出错。而retrofit通过简单的配置就可以实现上面复杂的过程。所以要想拆分retrofit就要主要分为三个方面来,请求数据的封装,请求对象生成及其如何发起网络请求的,最后对请求数据的封装。任何网络问题都逃不过这三部分。
1、请求数据(请求行、请求头、请求体)的封装。
2、生成请求对象发起请求。
3、响应数据的封装(响应行、响应头、响应体)。

2、retrofit的如何定制扩展。
扩展主要分为三个方面
第一方面、用谁来生成网络工作对象,在retrofit中虽然只能传入一个OkhttpClient对象,但是okhttp有丰富的扩展性,可以定制自己的拦截器,可以实现数据的缓存等。
第二方面、生成的网络工作对象进行转换(我们实际进行请求的是okhttp3里面的realCall,而在网络接口中定义的Call对象是在retrofit2中定义的,所以需要一个适配器进行转换),retrofit里面添加rxJava支持,可以返回一个Observable对象。
第三方面、对网络返回的数据进行解析,可以添加自己的数据解析器,定义自己的convertor类和ConvertorFactory类。

3、retrofit原理分析。

ServiceMethod 算是对请求数据的整体封装
动态代理首先会为每一方法生成一个ServiceMethod对象,存入缓存中,这个对象包含来网络请求所用到的一切,请求方法、请求的连接、请求头、callAdapter的适配器、convertor等信息。
如何找到合适的CallAdapter?
根据返回值找到对应的CallAdapter,如果是ExecuteCallAdapterFactory则返回的callAdapter对象为CallAdapter,如果是Rxjava则返回的是Rxjava2CallAdapter对象

1、获取当前方法的返回类型method.getGenericReturnType()。
2、遍历添加的CallAdapterFactory数组,通过每一个factory的get方法里面确认是否能创建该类型的对象,ExecutorCallAdapterFactory 代码如下

  @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }
      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

如何来确认responseConvertor对象呢?
通过泛型的返回值来进行选定的。Gson选定代码如下

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }

再来看一下如何生成对象请求对象的并发出请求的
创建一个retrofit2 包下的OkhttpCall对象。这个call对象里面有两个引用一个是ServiceMath对象一个是okhttp3包下的Call对象。
最后看一下返回的serviceMath.callAdapter.adapt(okhttpcall)方法
会生成一个ExecuteCallbackCall对象(默认的CallAdapterFactory),通过这个对象调用enqueue方法会调用retrofit2里面okhttpCall对象的enqueue方法,最终对调用okhttp3包下call 对象的enqueue方法。

数据转换
在retrofit2包下的okhttpCall对象,enqueue方法会对okhttp包下Call返回的数据进行解析,解析类是servicemath对象的reaponseConvertor对象,然后将解析好的数据返回回来。

4、以及阅读retrofit源码的感受。
分析网络框架可以从大的方面去着手,主要分为三步。
1、如何创建请求数据。
2、如何创建请求对象和发起请求。
3、如何对请求数据的处理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章