implementation 'com.squareup.retrofit2:retrofit:最新版本'
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Kotlin代码
interface GitHubService {
@GET("users/{user}/repos")
fun listRepos(@Path("user") user: String?): Call<List<Repo>>
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service =
retrofit.create(GitHubService.class);
Kotlin代码
//用Retrofit创建出interface的实例
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build()
val service:GitHubService = retrofit.create(GitHubService::class.java)
Call<List<Repo>> repos = service.listRepos("octocat");
Kotlin代码
//创建出service实例的对应方法,创建出对应的可以用来发送网络请求的call对象
val repos :Call<List<Repo>> = service.listRepos("octocat")
repos.enqueue(callback);
Kotlin代码
//使用 Call.execute() 或者 Call.enqueue() 来发起请求
repos.enqueue(callback);
repos.enqueue(object : Callback<List<Repo>?> {
override fun onResponse(call: Call<List<Repo>?>, response: Response<List<Repo>?>) {
TODO("Not yet implemented")
}
override fun onFailure(call: Call<List<Repo>?>, t: Throwable) {
}
})
通过 Retrofit.create(Class)
方法创建出 Service interface
的实例,从
而使得 Service
中配置的方法变得可用,这是 Retrofit
代码结构的核心;
Retrofit.create()
方法内部,使用的是Proxy.newProxyInstance()
方法来创建 Service
实例。这个方法会为参数中的多个 interface
(具体到 Retrofit 来说,是固定传入一个 interface
)创建一个对象,这个对象实现了所有 interface
的每个方法,并且每个方法的实现都是雷同的:调用对象实例内部的一个 InvocationHandler
成员变量的invoke()
方法,并把自己的方法信息传递进去。这样就在实质上实现了代理逻辑:interface
中的方法全部由一个另外设定的 InvocationHandler
对象来进行代理操作。并且,这些方法的具体实现是在运行时生成 interface
实例时才确定的,而不是在编译时(虽然在编译时就已经可以通过代码逻辑推断出来)。这就是网上所说的「动态代理机制」的具体含义。
因此, invoke()
方法中的逻辑,就是 Retrofit
创建 Service
实例的关键。这
个方法内有三行关键代码,共同组成了具体逻辑:
loadServiceMethod(method)
这行代码负责读取 interface 中原方法的信息(包括返回值类型、方法注解、参
数类型、参数注解),并将这些信息做初步分析。实际返回的是一个
CallAdapted 。
new OkHttpCall<>(requestFactory, args, callFactory,
responseConverter)
OkHttpCall 是 retrofit2.Call 的子类。这行代码负责将ServiceMethod 解读到的信息(主要是一个 RequestFactory 、一个OkHttpClient 和一个 ResponseConverter )封装进 OkHttpCall ;而这个对象可以在需要的时候(例如它的enqueue() 方法被调用的时候),利用 RequestFactory 和 OkHttpClient 来创建一个 okhttp3.Call对象,并调用这个okhttp3.Call 对象来进行网络请求的发起,然后利用ResponseConverter 对结果进行预处理之后,交回给 Retrofit 的Callback 。
callAdapter.adapt(call);
这个方法会使用一个 CallAdapter 对象来把 OkHttpCall 对象进行转换,生成一个新的对象。默认情况下,返回的是一个 ExecutorCallbackCall ,它的作用是把操作切回主线程后再交给 Callback 。另外,如果有自定义的 CallAdapter,这里也可以生成别的类型的对象,例如RxJava 的 Observable ,来让 Retrofit 可以和 RxJava 结合使用。
寻找切入点,而不是逐行通读
在阅读过程中,始终保有把看过的代码逻辑完整化的意识
尽量让每一刻都有一个确定的目标