1.使用方法
1、构造retrofit实例(建造者模式,类似于Dialog)
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
//https://api.github.com/repos/square/retrofit/contributors
GitHubApi repo = retrofit.create(GitHubApi.class);
2、创建同步或异步HTTP请求到远程网络服务器
Call<ResponseBody> call = repo.contributorsBySimpleGetCall("square", "retrofit");
3、网络请求
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Gson gson = new Gson();
ArrayList<Contributor> contributorsList = gson.fromJson(response.body().string(), new
TypeToken<List<Contributor>>() {
}.getType());
for (Contributor contributor : contributorsList) {
Log.d("login", contributor.getLogin());
Log.d("contributions", contributor.getContributions() + "");
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
2.源码解析
看看retrofit.create干了些啥
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//--------------------------------------newProxyInstance跟踪进去就是通过native函数实现的一个代理。不管怎样,成功后会调用invoke函数
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);
}
//--------------------------------------------重要的是下面三句
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
先看一下Platform.get
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();//--------------------------看一下Android的实现
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
Android平台的实现
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
//-------------------------------------------handler用来切换线程
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
接下来看最重要的三句话:
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);//----------------------------生成OkHttpCall接口
return serviceMethod.callAdapter.adapt(okHttpCall);
//--------------------------这段代码很简单,只要知道serviceMethodCache就是ConcurrentHashMap
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
最后serviceMethod.callAdapter.adapt(okHttpCall);
在Android中callAdapter默认的是ExecutorCallAdapterFactory。
adapt函数返回ExecutorCallbackCall实体类
最后看一下这段代码:
@Override public void enqueue(final Callback<T> callback) {
checkNotNull(callback, "callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
//-------------------------------------回调onResponse
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}