@GET(“user/{user}/repos”)
Call<List> listRepos(@Path(“user”) String user);
}
2、然后构建一个 Retrofit,通过 create 方法生成 GitHubService 的一个实现。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(“https://api.github.com/”)
.build();
GitHubService service = retrofit.create(GitHubService.class);
3、调用 listRepos 拿到 Call 实例,可以做同步或异步请求。
Call<List> repos = service.listRepos(“octocat”);
每个 Call 实例只能使用一次,但调用 clone() 将创建一个可以使用的新实例。
1. Retrofit 构建
1.1 Retrofit
首先看看 Retrofit 吧,这个类里面有7个实例变量。我们根据类型和变量名先猜猜是干什么用的,留个大体印象即可。
// 一个线程安全的、支持高效并发的HashMap,Key 是 Method,Value 是 ServiceMethod。Method 我们能猜到应该就是上面接口中定义的 listRepos,而这个方法中有很多注解,@GET、@Path 啥的,那这个 ServiceMethod 很有可能是这个方法的封装。而变量名带个 Cache 说明,会把这个 Method 对应的 ServiceMethod 缓存起来。
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
// 想必你知道 Retrofit 就是基于 OkHttp 的封装,那这个 Call.Factory,明显就是 Call 的工厂类。至于 Call 是干嘛的,负责创建 HTTP 请求,HTTP 请求被抽象为了 okhttp3.Call 类,它表示一个已经准备好,可以随时执行的 HTTP 请求;
final okhttp3.Call.Factory callFactory;
// 这个很好理解了,就是上面 基本使用 中的 baseUrl,可是这是个 HttpUrl 类型的,我们传的可是 String 类型的呀,那估计是通过 Builder 做了处理的。
final HttpUrl baseUrl;
// Converter 根据字面意思可得 这应该是个转换器,用于把我们的 响应 转换成特定的格式
final List<Converter.Factory> converterFactories;
// CallAdapter 根据字面意思,难道是对 Call 的一个适配?
final List<CallAdapter.Factory> callAdapterFactories;
// Executor 很熟悉了,这是个回调 Executor,想必就是用来切换线程的了
final @Nullable Executor callbackExecutor;
// 这个就猜不出了,只能暂时理解为一个标志位
final boolean validateEagerly;
再来看看 Retrofit 的构造函数
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
并没做什么特殊的处理,就是简单的赋值,那想必所有初始化的操作都在 Builder 里了。
那么成功建立一个 Retrofit 对象的标准就是:配置好Retrofit 里的成员变量。
-
callFactory : 网络请求 工厂
-
baseUrl :网络请求的基本 Url 地址
-
converterFactories :数据转换器 工厂集合
-
callAdapterFactories :网络请求适配器 工厂集合
-
callbackExecutor :回调方法执行器
1.2 Retrofit.Builder
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
// … …
}
我们可以看到 Builder 与 Retrofit 的参数几乎一样,只是少了 serviceMethodCache,多了个 Platform。这个 Platform 很重要。我们通过 Builder 的构造函数可以知道,调用了 Platform.get()方法,然后赋值给自己的 platform 变量。 我们看看这个 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();
}
// … …
}
get 方法会去调用 findPlatform 方法,这个里面很明显跟平台相关,Class.forName 要求 JVM 根据 className 查找并加载指定的类,如果未找到则抛出 ClassNotFoundException 。这里很明显我们分析 Android 平台,所以会 return 一个 Android()对象。
//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 MainThreadE