Retrofit使用
若要请求api
https://api.github.com/users/{user}/repos
需要先创建一个接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
然后创建一个Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.build();
GitHubService service = retrofit.create(GitHubService.class);
可以看到通过retrofit.create()
方法,retrofit为我们创建了一个GitHubService的实现,感觉很不可思议。
紧接着就可以通过这个GitHubService的实现对象去请求网络了
Call<List<Repo>> repos = service.listRepos("octocat");
// Fetch and print a list of the contributors to the library.
List<Contributor> contributors = call.execute().body();
看到这里总是很疑惑,retrofit是如何用我们提供的接口来为我们创建出一个实例的呢?
Retrofit调用流程
从上面我们可以看到service实例是通过retrofit.create()
方法获得的,那我们不看一下这个create()
方法
@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);
}
});
}
可以看到该方法返回的并不是一个service接口的实例,而是一个动态代理对象,而他又是怎么通过动态代理去发送网络请求的呢?我们就需要查看
return loadMethodHandler(method).invoke(args);
这行代码的返回结果了,去查看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;
}
可以看到该方法先去试图从methodHandler的缓存map中去寻找相应的methodHandler,若不存在再去创建对应方法的MethodHandler,获得了相应的MethodHandler实例后再去调用去invoke()
方法来发送请求。
继续查看MethodHandler的invoke()
方法
Object invoke(Object... args) {
return callAdapter.adapt(
new OkHttpCall<>(callFactory, requestFactory, args, responseConverter));
}
其中callAdapter.adapt()
方法负责把service中的返回类型转换成其他类型,例如RxJavaCallAdapter把返回结果转换成了Observable类型
可以看到adapt
方法中传入了一个OkHttpCall参数,而最后发送出网络请求的正是在该类的
@Override public void enqueue(final Callback<T> callback)
@Override public Response<T> execute() throws IOException
这两个方法中。相关的Http请求信息则封装在了requestFactory这个对象中。
这样整个流程就清楚了,可以看到这与我们一般使用动态代理的方法是不同的。这里对动态代理的使用是通过调用动态代理对象的相应方法,去生成一个Http请求再来发送这个请求。而service接口中方法的信息则是通过反射来得到的。
</br>
网友评论