浏览Retrofit源码收获

官网:http://square.github.io/retrofit/
github地址:https://github.com/square/retrofit

最近,在自己的工程里用到了Retrofit,确实好用;这几天,也抽空闲的时间,看了它的源码,学到了一些东西。今天,就抽时间来写这篇博客,来分享些我从Retrofit上学到的东西,比如Java类型(这里的类型不是指基本类型)、动态代理。

使用介绍

关于Retrofit 2.0的使用,大家可以看官网的使用介绍或者这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)(这篇博客很详细)。

代码分析

点开工程里的Retrofit(我这版本是2.3)的依赖包

这里写图片描述

http包下全是注解,所以不用管;大概有17个类文件,其中有4个接口。先看看类与类之间的关系

图1
图2
这里写图片描述
上面这三张图,是粗略画的UML类图(并不完全),是不是对类的关系有了大概地了解。

关于代码分析,推荐这篇博客(深入剖析 Retrofit 2.0 源码),就不介绍了;个人觉得源码应该自己抽时间看。看别人的分析,虽然很节约时间,但是收获相对地也会变少;因为每个人的认知不同,获得的收获肯定也不一样。如果有时间的话,还是自己看最好。

收获

get 技能点一

在图1和图2中,分别有个CallAdapter.Factory和Converter.Factory,它们都是抽象类,分别写在接口CallAdapter与Converter中;是不是很意外?(反正,我是很意外)还有这种写法,在接口中写了个类。

public interface CallAdapter<R, T> {

  Type responseType();

  T adapt(Call<R> call);

  abstract class Factory {

    public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);

    protected static Type getParameterUpperBound(int index, ParameterizedType type) {

      return Utils.getParameterUpperBound(index, type);

    }

    protected static Class<?> getRawType(Type type) {

      return Utils.getRawType(type);

    }
  }
}

我们经常在接口中,写未实现的方法和常量;原来,接口中也可以写一个内部类;这里的抽象类Factory就是用来构建实现了CallAdapter接口的类实例,其作用类似于工厂。

get 技能点二

  Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)// 设置网络请求的Url地址
                .callFactory(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
public interface Request {

    /***
     * 请求当前城市的正在热映的电影
     * @param city  城市
     * @return
     */
    @GET("v2/movie/in_theaters")
    Observable<Message> getHitMessage(@Query("city") String city);
}

调用create()转入个class文件。用到这个方法的时候,第一时间就想到了反射机制(对Java反射机制不是很了解的朋友,可以参考这篇博客Java类型信息(Class对象)与反射机制;但是Request是个接口,我根本没有实现它,Retrofit是会怎么处理呢?这是我当时的疑问。

 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, @Nullable Object[] args)
              throws Throwable {

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

在create方法中返回Proxy.newProxyInstance;Proxy是什么?第一次见,点开它;原来它在java.lang.reflect包下,其作用就是代理,也就是动态代理。这个类的用法,大家可以看Java文档或者这篇博客(动态代理的实现)。

get 技能点三

在看Utils类文件中的getRawType方法时

static Class<?> getRawType(Type type) {

    checkNotNull(type, "type == null");

    if (type instanceof Class<?>) {
        // Type is a normal class.
        return (Class<?>) type;
    }

    if (type instanceof ParameterizedType) {

        ParameterizedType parameterizedType = (ParameterizedType) type;

        Type rawType = parameterizedType.getRawType();
        if (!(rawType instanceof Class)) throw new IllegalArgumentException();
        return (Class<?>) rawType;
    }

    if (type instanceof GenericArrayType) {

        Type componentType = ((GenericArrayType) type).getGenericComponentType();

        return Array.newInstance(getRawType(componentType), 0).getClass();
    }

    if (type instanceof TypeVariable) {

        return Object.class;
    }

    if (type instanceof WildcardType) {

        return getRawType(((WildcardType) type).getUpperBounds()[0]);
    }

    throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
          + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
  }

看到了几个陌生的类,比如GenericArrayType、TypeVariable等,这几个类也是在java.lang.reflect包下。通过Java文档介绍和网上的博客,get到了一个新概念(以前不知道,还有这种东西),就是Java Type(推荐这篇博客Java Type 详解);这里类型并不是指基本类型,比如int、long等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值