您的位置:首页 > 其它

Retrofit详解(一)(Retrofit创建过程)

2016-04-18 14:43 477 查看
作为一个coder 最悲哀的莫过于知其然,不知其所以然。

闲暇之余,研究研究Retrofit源码,为了防止大篇幅的代码,看得头晕眼花,这章仅仅详细介绍Retrofit 的创建过程。Retrofit使用方法这里就不介绍了,请看我前面写的博客。

首先贴上需要提前展示的APIService:

public interface UserService {
@POST(Constants.URL_UPDATE_USER_LIST)
Observable<BaseResponse<List<User>>> updateUserList(@Query("userList") String userList);
}


Retrofit retrofit = new Retrofit.Builder()
.baseUrl(getEndPoint(t))
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(clientBuilder.build())
.build();
service = retrofit.create(t);


如上所述使用retrofit 访问网络就是这么简单,那么Retrofit框架怎样实现的呢?请往下看

Retrofit类有一个静态内部类Builder,调用Builder的build()方法就能生成Retrofit对象,看看它的成员变量,是不是觉得网络访问的几要素都具备了?

网络请求工具、线程处理工具、网络访问回调处理工具、网络访问结果解析工具。

public static final class Builder {
private Platform platform;
private okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private List<Converter.Factory> converterFactories = new ArrayList<>();
private List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
private Executor callbackExecutor;
private boolean validateEagerly;

Builder(Platform platform) {
this.platform = platform;
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
}

public Builder() {
this(Platform.get());
}


首先来看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) {
}
try {
Class.forName("org.robovm.apple.foundation.NSObject");
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}


第一个默认就是查找是否是Andriod平台,当然后面还有Java8,IOS的Platform,有兴趣可以查看源码,先来看看Android:

static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}

@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
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);
}
}
}

是不是看到熟悉的东西了,没错,它就是Handler,现在是不是觉得Retrofit底层也是利用了Handler?

仔细查看相关源码就能得出以下描述:

调用默认的Retrofit.Builder()方法默认会自动判断platform为Andriod,然后赋值给Retrofit.Builder类的platform变量。

.baseUrl(String url)方法解析我们传入的url参数生成一个HttpUrl对象存放于Retrofit. Builder类的成员变量baseUrl中。

.addConverterFactory方法添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。从Builder的构造方法可以看出创建Builder的时候会自动添加一个默认的ConvertFactory,我们也可以调用多次addConverterFactory添加多个ConvertFactory,处理结果的时候会按添加顺序优先匹配,一旦匹配上前面的,就丢弃后面的,当然我们能添加自己定义的ConvertFactory只要继承Converter.Factory,详细放在后面讲解。

.addCallAdapterFactory方法添加访问处理适配器,存放于Retrofit.Builder类的adapterFactories集合中。

.client方法用于添加网络访问工具OKHttpClient,保存在Retrofit.Builder类的callFactory变量中.

调用.build()方法,通过platform设置Retrofit.Builder类的callbackExcutor变量,然后最终会生成一个Retrofit对象。

public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}

okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}

Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}

// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

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

return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}


再来看看Retrofit的成员变量和构造方法:

public final class Retrofit {
private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();

private final okhttp3.Call.Factory callFactory;
private final HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories;
private final List<CallAdapter.Factory> adapterFactories;
private final Executor callbackExecutor;
private final boolean validateEagerly;

Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}

这就像是将它的静态内部类Builder里的成员变量搬过来的。serviceMethodCache是一个存储方法(当然是我们定义在接口里的方法啦)Map,后面会用到。

到这里Retrofit总算是被我们给new出来了,下一章就该讲解我们需要的Api Service的创建以及访问了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: