您的位置:首页 > 移动开发 > Android开发

retrofit2源码分析

2017-03-27 17:15 302 查看
Retrofit官网 http://square.github.io/retrofit/

分析源码基本上都是从demo开始的

首先知道如何调用官网首页给的例子

1.先定义一个接口

首页api声明中明确指出每个接口方法必须包含http请求方法注解
GET
POST
PUT
DELETE
,
and 
HEAD,
并且可以加入请求参数

具体 @Path @QueryMap @FormUrlEncoded  @Multipart 等格式写法请参考官方文档


public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
2.创建根据接口创建 retrofit实现

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();

GitHubService service = retrofit.create(GitHubService.class);3.进行网络请求
Call<List<Repo>> repos = service.listRepos("octocat");
到此请求完成

接下来具体分析代码流程

首先定义接口 GitHubService 抽象要完成的数据请求

创建retrofit实例是通过build完成的

public Builder() {
this(Platform.get());
}
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();
}
根据是android还是java平台返回具体实现
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);
}
}
}
Android代码包含一个CallAdapter.Factory和MainThreadExecutor
MainThreadExecutor中只有一个handler.post(runnable)

CallAdapter.Factory是根据返回值类型创建返回值

然后是执行baseUrl("https://api.github.com/")方法
/**
* Set the API base URL.
*
* @see #baseUrl(HttpUrl)
*/
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
HttpUrl(Builder builder) {
this.scheme = builder.scheme;
this.username = percentDecode(builder.encodedUsername, false);
this.password = percentDecode(builder.encodedPassword, false);
this.host = builder.host;
this.port = builder.effectivePort();
this.pathSegments = percentDecode(builder.encodedPathSegments, false);
this.queryNamesAndValues = builder.encodedQueryNamesAndValues != null
? percentDecode(builder.encodedQueryNamesAndValues, true)
: null;
this.fragment = builder.encodedFragment != null
? percentDecode(builder.encodedFragment, false)
: null;
this.url = builder.toString();
}
创建了httpurl类封装了请求地址以及端口号以及参数编解码信息等信息
然后执行build()方法创建Retrofit实例/**
* Create the {@link Retrofit} instance using the configured values.
* <p>
* Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
* OkHttpClient} will be created and used.
*/
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);
}
build方法中首先创建了请求网络实例 callFactory =
new
OkHttpClient();

然后根据平台类型设置callbackExecutor类即android中的handler

然后将平台处理CallAdapter.Factory放到retrofit中,然后创建出retrofit实例

到现在并没有看到GitHubService的具体实现代码

下面进入retrofit.create(GitHubService.class);方法

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);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}首先通过Utils.validateServiceInterface判断参数是否是接口,并且接口不能继承其它接口
然后根据接口系统直接创建代理类返回

最后调用接口方法执行具体操作

因为代理类重写了

@Override public Object invoke(Object proxy, Method method, Object[] args)

方法所有方法执行都会进入此方法内进行具体处理

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;
}

首先执行的是此方法会将方法请求进行缓存以防每次都新建
从代码可以看出会根据method创建出ServiceMethod,
ServiceMethod中包涵接口方法中的返回参数,方法注解以及参数中的注解处理,返回值处理等信息


然后根据ServiceMethod创建new
OkHttpCall<>(serviceMethod, args);

最后调用serviceMethod.callAdapter.adapt(okHttpCall)

真正执行的代码为Android平台下的ExecutorCallAdapterFactory

class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;

ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}

@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}

@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}serviceMethod.callAdapter.adapt(okHttpCall)调用了此处的adapt(Call<Object>
call) 方法,

ExecutorCallbackCall与handler进行交互处理进而与返回值进行取消网落操作处理


具体网络请求代码在okHttp中请自己查看

关于Converter.Factory okHttp代码具体细节代码未涉及

到此关于retrofit的代码到此结束本
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android