Retrofit源码解析

square公司开源了一系列的优秀库,比如Retrofit,OkHttp,Picasso等,
前面简单分析了Picasso的源码,这里来分析下Retrofit的使用:

一、gradle添加依赖

compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.4.0'
compile 'com.squareup.okio:okio:1.5.0'
compile 'com.google.code.gson:gson:2.2.4'

compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'

compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'

盗两张网上的图:
下面是从创建Retrofit出发,具体的使用流程;Retrofit最终的请求操作都是交由okHttp去执行的,执行的结果返回Response,再根据转换器进行解析成相对应的返回类型T;
Retrofit中使用了动态代理,方便了使用;通过retrofit.create返回的其实是个动态代理类,所有具体的处理逻辑交由MethodHandler进行处理;
这里写图片描述
下面是Retrofit系统中的整个类图,有点像外观模式,Retrofit持有所有子系统的引用;Retrofit比较重要的是两个Factory,一个使用来生成CallAdapter的CallAdapterFactory;一个是用来转换结果的ConvertFactory;这两个都可以用户自己进行添加。
在自定义的Service中,每一个method对应一个MethodHandler,MethodHandler持有retrofit,前面两个Factory以及生成Request的RequestFactory;在okHttp中,Request需要自己进行定义创建,而Retrofit简化了这个操作,进行了相应的封装,使用注解的方式来定义Request的相关参数信息;注解信息的解析则在RequestFactory中完成,通过RequestFactoryParser对注解信息进行简单解析,RequestBuilderAction是解析method中参数中的注解如@Path这些产生的中间产物,最终通过RequestBuilder来具体产生一个Request,RequestBuilder中持有okHttp中的Request.Builder类的引用,其创建Request过程其实都是交给okHttp来操作的;
生成的Request最终封装成为一个OkHttpCall,OkHttpCall则可以看做是对okHttp中Call的通过,它的enqueue等网络请求操作都是委托个给okHttp来操作的;同时对okHttp的返回Response进行解析,使用convertFactory,将其解析为用户所期望的返回类型;
这里写图片描述

二、使用

(一)使用Call形式

1、定义请求接口:

public interface RetrofirHttpService {
    @GET("{user}")
    Call<UserInfo> getData(@Path("user") String user);
}
注:UserInfo是自己定义的解析类:
public class UserInfo {
    String username;
    String password;
}

2、使用GET获取信息:

// 原始的CallBack方式
private void getUseCall() {
    // 添加拦截器
    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new LoggingInterceptor());

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://115.156.187.146/TransferServer/")
            .client(client)                                     // 添加okHttp
            .addConverterFactory(GsonConverterFactory.create()) // GSON进行转换
            .build();
    RetrofirHttpService apiStores = retrofit.create(RetrofirHttpService.class);
    Call<UserInfo> call = apiStores.getData("ServerMain.php");

    // 异步调用
    call.enqueue(new Callback<UserInfo>() {
        @Override
        public void onResponse(Response<UserInfo> response, Retrofit retrofit) {
            UserInfo data = response.body();
            LogUtils.i("Call Result:" + data.m);
        }

        @Override
        public void onFailure(Throwable t) {
            LogUtils.e(t.toString());
        }
    });
}

(二)使用RxJava形式

1、定义请求接口

public interface RxHttpService {
   
    @GET("{path}")
    Observable<UserInfo> getData(@Path("path") String path);
}

2、具体使用

// 使用RxJava方式
private void getUseRxJava() {
    // 添加拦截器
    OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new LoggingInterceptor());

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://115.156.187.146/TransferServer/")
            .client(client)  // 添加okHttp
            .addConverterFactory(GsonConverterFactory.create()) // GSON进行转换
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

    RxHttpService apiStores = retrofit.create(RxHttpService.class);
    Observable<UserInfo> observable = apiStores.getData("ServerMain.php");
    observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<UserInfo>() {
                @Override
                public void onNext(UserInfo user) {
                    LogUtils.i("Call Result:" + user.m);
                }

                @Override
                public void onCompleted() {
                }

                @Override
                public void onError(Throwable error) {
                    LogUtils.e(error.toString());
                }
            });
}

三、源码分析:

(一)先来看创建动态代理类的过程:

RxHttpService apiStores = retrofit.create(RxHttpService.class);

动态代理的知识具体见《 设计模式汇总:结构型模型(上)》中的代理模式中的解释。

1)Retrofit#create:

/** Create an implementation of the API defined by the {@code service} interface. */
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
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);
                    }
                    return loadMethodHandler(method).invoke(args);
                }
            });
}

标准的动态代理创建过程;
来看代理类和委托类之间的中间InvocationHandler类的invoke函数具体执行逻辑;
loadMethodHandler(method).invoke(args);

2)Retrofit#loadMethodHandler:

private final Map<Method, MethodHandler<?>> methodHandlerCache = new LinkedHashMap<>();

MethodHandler<?> loadMethodHandler(Method method) {
    MethodHandler<?> handler;
    synchronized (methodHandlerCache) {
        handler = methodHandlerCache.get(method);
        if (handler == null) {
            handler = MethodHandler.create(this, method);
            methodHandlerCache.put(method, handler);
        }
    }
    return handler;
}

Retrofit维护了一个method对应的Map,这里将method都封装成一个MethodHandler类(可以当作是委托类);调用代理类,其实就是调用MethodHandler的invoke;所以具体的实现逻辑都在MethodHandler中;

(二)MethodHanlder

1)MethodHandler类:

final class MethodHandler<T> {
    // MethodHandler持有一个retrofit对象
    private final Retrofit retrofit;
    // 类似于Volley中的 Request ,包含了HTTP请求的Url、Header信息,MediaType、Method以及RequestAction数组
    private final RequestFactory requestFactory;
    // HTTP请求返回数据的类型
    private final CallAdapter<T> callAdapter;
    // 对返回数据进行转换的类型转换器
    private final Converter<ResponseBody, T> responseConverter;

    private MethodHandler(Retrofit retrofit, RequestFactory requestFactory,
                          CallAdapter<T> callAdapter, Converter<ResponseBody, T> responseConverter) {
        this.retrofit = retrofit;
        this.requestFactory = requestFactory;
        this.callAdapter = callAdapter;
        this.responseConverter = responseConverter;
    }

    // 每一次请求的最终具体调用的函数
    Object invoke(Object... args) {
        // 可以发现最终是调用callAdapter的adapt函数
        // 并且将相应的请求事务封装成一个OkHttpCall类进行处理
        return callAdapter.adapt(new OkHttpCall<>(retrofit, requestFactory, responseConverter, args));
    }

    // 调用该静态类创建一个MethodHandler实例
    @SuppressWarnings("unchecked")
    static MethodHandler<?> create(Retrofit retrofit, Method method) {
        // 创建CallAdapter
        CallAdapter<Object> callAdapter = (CallAdapter<Object>) createCallAdapter(method, retrofit);
        // 根据callAdapter来获取相应的返回类型
        Type responseType = callAdapter.responseType();
        // 创建结果类型转换器
        Converter<ResponseBody, Object> responseConverter =
                (Converter<ResponseBody, Object>) createResponseConverter(method, retrofit, responseType);
        // 创建RequestFactory
        RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);
        return new MethodHandler<>(retrofit, requestFactory, callAdapter, responseConverter);
    }

    // 创建相应的CallAdapter
    private static CallAdapter<?> createCallAdapter(Method method, Retrofit retrofit) {
        // 这个method即为service中自定义的一个方法,一般返回都是泛型类
        Type returnType = method.getGenericReturnType();
        if (Utils.hasUnresolvableType(returnType)) {
            throw Utils.methodError(method,
                    "Method return type must not include a type variable or wildcard: %s", returnType);
        }
        if (returnType == void.class) {
            throw Utils.methodError(method, "Service methods cannot return void.");
        }
        // 获取Method上对应的注解即(GET这些)
        Annotation[] annotations = method.getAnnotations();
        try {
            // 根据注解来获取相应的Adapter
            return retrofit.callAdapter(returnType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw Utils.methodError(e, method, "Unable to create call adapter for %s", returnType);
        }
    }

    // 最后也是调用retrofit来实现的;
    private static Converter<ResponseBody, ?> createResponseConverter(Method method,
                                                                      Retrofit retrofit, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        try {
            return retrofit.responseConverter(responseType, annotations);
        } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw Utils.methodError(e, method, "Unable to create converter for %s", responseType);
        }
    }
}

MethodHandler是系统为定义的每一个Service中的method中创建的一个具体执行类,通过调用其invoke函数,来执行具体的请求的逻辑;
它主要包含四个变量:
Retrofit: MethodHandler持有一个retrofit对象
private final Retrofit retrofit;
RequestFactory: 类似于Volley中的 Request ,包含了HTTP请求的Url、Header信息,MediaType、Method以及RequestAction数组
private final RequestFactory requestFactory;
CallAdapter: HTTP请求返回数据的类型
private final CallAdapter<T> callAdapter;
ResponseConverter: 对返回数据进行转换的类型转换器
private final Converter<ResponseBody, T> responseConverter;
具体来看每个变量的创建;

2)Retrofit#callAdapter:

private final List<CallAdapter.Factory> adapterFactories;

public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
}
/**
 * Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
 * #callAdapterFactories() factories} except {@code skipPast}.
 */
// 返回相关的可用的CallAdapter(除了指定跳过的skipPast)
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
                                      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = adapterFactories.indexOf(skipPast) + 1;
    // 遍历adapterFactories中所有的Factory
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
        CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
        // 如果找到,则返回该Adapter
        if (adapter != null) {
            return adapter;
        }
    }

    // 如果获取不到相应的CallAdapter,则抛出异常
    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
            .append(returnType)
            .append(". Tried:");
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
        builder.append("\n * ").append(adapterFactories.get(i)
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值