Retrofit2源码解析(一)

Retrofit2源码解析系列

本文基于Retrofit2的2.4.0版本php

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
复制代码

Retrofit2底层基于OkHttp3,是对利用OkHttp3请求网络的一种封装,可使咱们避免写不少重复的调用网络请求的代码,同时灵活性很高,能够定制自定义的OkHttpClient、自定义的数据解析转换器(好比Gson、Jackson等)、自定义的请求转换器(好比结合RxJava)。java

Retrofit2的另外一个特色就是使用运行时注解,咱们在使用时能够根据须要来利用注解将咱们的业务调用接口转换成Http请求的接口。android

下面先来看看咱们使用Retrofit2发起网络请求的步骤bash

(1)建立咱们的具体业务接口,这里好比咱们调用淘宝的IP地址库微信

public interface MyService {
    @GET("getIpInfo.php=11.11.11.11")
    Call<IpBean> getData();
}

复制代码

(2)建立Retrofit网络

retrofit = new Retrofit.Builder()
    .baseUrl("https://ip.taobao.com/service/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
复制代码

可见Retrofit2采用的是Builder模式来构建的ide

(3)利用Retrofit建立咱们的接口对象,生成Call对象,并调用请求网络方法oop

MyService myService = retrofit.create(MyService.class);
Call<IpBean> call = myService.getData();
call.enqueue(new Callback<IpBean>() {
    @Override
    public void onResponse(Call<IpBean> call, Response<IpBean> response) {
        
    }

    @Override
    public void onFailure(Call<IpBean> call, Throwable t) {
        
    }
});
复制代码

Retrofit的建立

首先咱们看看建立Retrofit时都作了哪些工做post

public Retrofit build() {
    //这里能够看出咱们必需设置baseUrl
    if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
    }
    
    //若是咱们没有设置自定义的OkHttpClient,就用默认的OkHttpClient
    okhttp3.Call.Factory callFactory = this.callFactory;
    if (callFactory == null) {
        callFactory = new OkHttpClient();
    }
    
    //这个callbackExecutor用于回调到UI线程
    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
    }

    //将咱们设置的Call适配器添加到列表中,好比RxJava的适配器
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    //添加默认的Call适配器
    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

    // Make a defensive copy of the converters.
    List<Converter.Factory> converterFactories =
            new ArrayList<>(1 + this.converterFactories.size());

    //添加数据转换器,用于将网络请求返回的结果转换成咱们须要的类型
    converterFactories.add(new BuiltInConverters());
    converterFactories.addAll(this.converterFactories);
    
    //构建Retrofit
    return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
            unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
复制代码

经过上面Retrofit2的Builder的build方法,咱们能够看出在Retrofit2中主要有这么几个部分:ui

(1)用于执行具体网络请求的callFactory,也就是OkHttpClient。因此说Retrofit2是基于OkHttp3的封装。

(2)callbackExecutor回调执行器,这个是用于网络请求返回后回调到主线程的。咱们知道,在利用OkHttp3进行网络请求时,咱们须要手动回调到主线程,以便更新UI。那咱们来看看这个默认的defaultCallbackExecutor是否是这样。

//Retrofit.class
public Builder() {
    this(Platform.get());
}

Builder(Platform platform) {
    this.platform = platform;
}
复制代码

能够看到在Builder中调用的是Platform的get方法,返回对应的平台,而后在build方法里经过platform的defaultCallbackExecutor获得咱们的回调器。下面咱们看看这个Platform类

class Platform {
    private static final Platform PLATFORM = findPlatform();

    static Platform get() {
        return PLATFORM;
    }

    private static Platform findPlatform() {
        try {
            Class.forName("android.os.Build");
            if (Build.VERSION.SDK_INT != 0) {
                return new Android();
            }
        } catch (ClassNotFoundException ignored) {
        }
        try {
            Class.forName("java.util.Optional");
            return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
    }
    
    ...
    
    static class Android extends Platform {
        @Override
        public Executor defaultCallbackExecutor() {
            return new MainThreadExecutor();
        }

        @Override
        CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
            if (callbackExecutor == null) throw new AssertionError();
            return new ExecutorCallAdapterFactory(callbackExecutor);
        }

        static class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());

            @Override
            public void execute(Runnable r) {
                handler.post(r);
            }
        }
    }
}
复制代码

从上面的源码中咱们能够看到Platform中会根据当前运行的平台返回不一样的子类,这里固然就是Android这个内部类了。因此当咱们调用platform的defaultCallbackExecutor时,实际上调用的是Android这个类的defaultCallbackExecutor方法,而这个方法返回的是MainThreadExecutor,它的做用就是利用handler将执行结果回调到主线程中。

(3)callAdapterFactories适配器列表,这里面存放的是全部的Call适配器CallAdapter。这个CallAdapter是干吗的呢?咱们知道Retrofit2底层是用Okhttp3来请求网络的,那势必是经过OkHttp3的Call来执行请求,可是咱们在实际使用Retrofit2时,可能须要结合请他的三方库,常见的好比RxJava,那咱们接口中所须要返回的可能就是Observable而不是Call了。

@GET("getIpInfo.php?ip=11.11.11.11")
Observable<IpBean> getObservableData();
复制代码

因此Retrofit2就须要一个Call适配器CallAdapter,来将Call转换为咱们须要的Observable,这就是CallAdapter的做用。

(4)converterFactories返回结果转换器列表,这里面存放的是将网络返回结果,也就是OkHttp3返回的Response,解析转换成咱们须要的实际类型,好比IpBean实体类。如GsonConverterFactory就是一个经常使用的转换器,至关于Retrofit2把咱们直接使用Okhttp3来请求网络数据时须要将返回结果进行Gson解析的动做也替咱们作了。

总结

(1)这里咱们简单分析了Retrofit的建立过程,能够发现Retrofit中核心部分包括OkHttpClient、Call适配器、Response转换器以及用于将请求回调到UI线程的回调执行器等。

(2)Retrofit的建立采用的是Builder模式,定制化程度很高,咱们能够设置本身的OkHttpClient,也能够实现自定义的Call适配器和Response转换器,以及请求的回调执行器。

(3)可见Retrofit虽然作了很大程度的封装,可是灵活性扩展性依然很高,咱们几乎能够扩展更改网络请求的大部分过程。

今天咱们先浅尝则止,后面咱们再来具体分析下Retrofit2的网络调用过程,看看Retrofit2是怎么利用适配器模式来为咱们提供强大的灵活性的,敬请期待。


欢迎关注个人微信公众号,和我一块儿天天进步一点点!
复制代码

AntDream
相关文章
相关标签/搜索