一、retrofit使用
interface RequestService {
@GET
operator fun get(@Url url: String,@QueryMap params: HashMap<String, @JvmSuppressWildcards Any>): Call<String>
}
val client = Retrofit.Builder().apply {
baseUrl("xxx")
client(OkHttpHolder.okHttpClient)
}.build()
val service: RequestService = client.create(RequestService::class.java)
val call: Call<String> = service.get("xxx",HashMap<String, String>())
call.enqueue(object :Callback<String>{
override fun onResponse(call: Call<String>, response: Response<String>) {
}
override fun onFailure(call: Call<String>, t: Throwable) {
}
})
二、DefaultCallAdapterFactory.ExecutorCallbackCall
service.get("xxx",HashMap<String, String>())
通过源码可知,在调用get时,通过代理,会得到DefaultCallAdapterFactory.ExecutorCallbackCall,而ExecutorCallbackCall就是接口Call的实现类,那么,call.enqueue()时,将会执行ExecutorCallbackCall的enqueue方法,看下ExecutorCallbackCall的enqueue(final Callback<T> callback)源码:
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(
() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on
// cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
@Override
public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
显然,线程就是通过callbackExecutor.execute()切换的,看下callbackExecutor怎么来的。
通过代码追踪,发现,callbackExecutor来自Retrofit中的build(),而当我们创建Retrofit的时候,就调用了这个方法。
三、Retrofit.build()
public final class Retrofit {
public Retrofit build() {
//这里仅贴出获取callbackExecutor的代码
...
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
...
}
public static final class Builder {
public Builder() {
this(Platform.get());
}
}
}
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Android() //
: new Platform(true);
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
}
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
platform是通过Platform.get()获取的,System.getProperty("java.vm.name")获取的是java VM的名称,显然,Android系统下将返回Android(),Android是Platform实现类,当调用latform.defaultCallbackExecutor()时,将返回一个MainThreadExecutor对象,而,当执行MainThreadExecutor.execute的时候,通过new Handler(Looper.getMainLooper())讲子线程切到了UI线程。
四、如何让Retrofit请求结束后的回调中还在子线程
val client = Retrofit.Builder().apply {
baseUrl("")
callbackExecutor(ThreadExecutor())
addConverterFactory(ScalarsConverterFactory.create())
client(OkHttpHolder.okHttpClient)
}.build()
class ThreadExecutor : Executor {
override fun execute(r: Runnable) {
r.run()
}
}
给Retrofit重新创造一个Executor就行了。
网友评论