Android—Retrofit解析

设计模式:

外观模式,构建者模式,工厂模式,代理模式,适配器模式,策略模式,观察者模式

Retrofit网络通信八步骤

  1. 创建Retrofit实例
  2. 定义网络请求接口,并为接口中的方法添加注解
  3. 通过动态代理生成网络请求对象
  4. 通过网络请求适配器将网络请求对象进行平台适配
  5. 通过网络请求执行器,发送网络请求(call)
  6. 通过数据解析器解析数据
  7. 通过回调执行器,切换线程
  8. 用户在主线程处理返回结果
@GET("/user/{user}/repos")
Call<ResponseBody> find(@Path("user") String user);

//call封装了整个okhttp的请求

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.github.com/")
        .addConverterFactory(GsonConverteractory.create())
        //.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build();

//动态生成代理对象
Request req = retrofit.create(Request.class);
//生成一个OKHttpCall的代理对象
Call<ResponseBody> call = req.find(“Mike”);
//返回结果
Response<ResponseBody> response = call.execute();

先看Create方法

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
        eagerlyValidateMethods(service);
    }
    //重点看这里
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
                private final Platform platform = Platform.get();

                @Override public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    // If the method is a method from Object then defer to normal invocation.
                    if (method.getDeclaringClass() == Object.class) {
                        return method.invoke(this, args);
                    }
                    if (platform.isDefaultMethod(method)) {
                        return platform.invokeDefaultMethod(method, service, proxy, args);
                    }
                 
                    ServiceMethod<Object, Object> serviceMethod =
                            (ServiceMethod<Object, Object>) loadServiceMethod(method);

                    
                    OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);

                 
                    return serviceMethod.callAdapter.adapt(okHttpCall);
                }
            });
}

使用了动态代理,Proxy.newProxyInstance()返回一个代理类对象。

invoke方法接收三个参数,动态代理对象、我们调用的方法、参数数组;

loadServiceMethod方法:

ServiceMethod loadServiceMethod(Method method) {
  ServiceMethod result;
  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
    result = new ServiceMethod.Builder(this, method).build();
    serviceMethodCache.put(method, result);
    }
  }
  return result;
}

Build类:

public Builder(Retrofit retrofit, Method method) {
  this.retrofit = retrofit;
  this.method = method;
  // 获取 method 中的所有注解
  this.methodAnnotations = method.getAnnotations();
  // 获取 method 中方法的参数类型
  this.parameterTypes = method.getGenericParameterTypes();
  // 获得参数的值
  this.parameterAnnotationsArray = method.getParameterAnnotations();
}

build()方法主要内容

// 根据 retrofit 对象的 CallAdapterFactory 为 ServiceMethod 创建一个 callAdapter
callAdapter = createCallAdapter();
// 根据 retrofit 对象创建一个 responseConverter,默认是一个 BuildInConveter
responseConverter = createResponseConverter();
// 解析 method 的所有注解
for (Annotation annotation : methodAnnotations) {
    parseMethodAnnotation(annotation);
}

所以ServiceMethod主要封装了callAdapterresponseConverter ,对注解进行了解析,对后面网络请求做准备。

看回Create方法的代码

return serviceMethod.callAdapter.adapt(okHttpCall);

最后是调用了callAdapter的adapt方法,如果我们添加了RxJava2CallAdapter

@Override
public Object adapt(Call<R> call) {
    Observable<Response<R>> responseObservable = isAsync
            ? new CallEnqueueObservable<>(call)
            : new CallExecuteObservable<>(call);

    Observable<?> observable;
    if (isResult) {
        observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
        observable = new BodyObservable<>(responseObservable);
    } else {
        observable = responseObservable;
    }

    if (scheduler != null) {
        observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
        return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
        return observable.singleOrError();
    }
    if (isMaybe) {
        return observable.singleElement();
    }
    if (isCompletable) {
        return observable.ignoreElements();
    }
    return observable;
}

所以如果添加了RxJava2CallAdapter就返回observal对象。

Retrofit中还有一个Converter ,与CallAdapter一样重要,用户可以根据需求对这两个进行自由扩展。

Okhttp中服务器返回的数据源就是ResponseBody对象。所以我们的目标就是对ResponseBody进行解析:

T convert(ResponseBody value){
  //do convert and return t
}

 Retrofit不仅可以对ResponseBody进行转换,也可以对RequestBody进行转换;具体其内部提供了一个Convert.Factory:

abstract class Factory {
    //对ResponseBody进行数据转换的转换器
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
        Annotation[] annotations, Retrofit retrofit) {
      return null;
    }

    //将未知数据转换成RequestBody的转换器
    public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
      return null;
    }

    //将未知数据转换成String类型的数据转换器
    public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
        Retrofit retrofit) {
      return null;
    }
}

开头构建Retrofit对象的

.addConverterFactory(GsonConverterFactory.create()) //添加Gson

就是用来添加Gson对象的

  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  public static GsonConverterFactory create(Gson gson) {
    return new GsonConverterFactory(gson);
  }
  
  class GsonConverterFactory extends Converter.Factory{
     //持有一个gson对象用来讲原始数据转换成JavaBean
     private final Gson gson;

     private GsonConverterFactory(Gson gson) {
       this.gson = gson;
      }
  }

具体转换过程可以看Gson原理分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值