提交 cb5c9cec 编写于 作者: J Jake Wharton

Propagate callback executor even when not explicitly specified.

This lets custom CallAdapter implementations use the platform default for their callbacks.
上级 d41d49c5
......@@ -53,6 +53,10 @@ class Platform {
return new Platform();
}
Executor defaultCallbackExecutor() {
return null;
}
CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
......@@ -89,10 +93,11 @@ class Platform {
}
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
if (callbackExecutor == null) {
callbackExecutor = new MainThreadExecutor();
}
return new ExecutorCallAdapterFactory(callbackExecutor);
}
......@@ -106,10 +111,11 @@ class Platform {
}
static class IOS extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
if (callbackExecutor == null) {
callbackExecutor = new MainThreadExecutor();
}
return new ExecutorCallAdapterFactory(callbackExecutor);
}
......
......@@ -358,7 +358,10 @@ public final class Retrofit {
return (Converter<T, String>) BuiltInConverters.ToStringConverter.INSTANCE;
}
/** The executor used for {@link Callback} methods on a {@link Call}. */
/**
* The executor used for {@link Callback} methods on a {@link Call}. This may be {@code null},
* in which case callbacks should be made synchronously on the background thread.
*/
public Executor callbackExecutor() {
return callbackExecutor;
}
......@@ -370,6 +373,7 @@ public final class Retrofit {
* are optional.
*/
public static final class Builder {
private Platform platform;
private okhttp3.Call.Factory callFactory;
private BaseUrl baseUrl;
private List<Converter.Factory> converterFactories = new ArrayList<>();
......@@ -377,12 +381,17 @@ public final class Retrofit {
private Executor callbackExecutor;
private boolean validateEagerly;
public Builder() {
Builder(Platform platform) {
this.platform = platform;
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
}
public Builder() {
this(Platform.get());
}
/**
* The HTTP client used for requests.
* <p>
......@@ -545,9 +554,14 @@ public final class Retrofit {
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.get().defaultCallAdapterFactory(callbackExecutor));
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
......
......@@ -11,6 +11,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
......@@ -1156,13 +1157,26 @@ public final class RetrofitTest {
}
}
@Test public void callbackExecutorNoDefault() {
@Test public void callbackExecutorPropagatesDefaultJvm() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.build();
assertThat(retrofit.callbackExecutor()).isNull();
}
@Test public void callbackExecutorPropagatesDefaultAndroid() {
final Executor executor = Executors.newSingleThreadExecutor();
Platform platform = new Platform() {
@Override Executor defaultCallbackExecutor() {
return executor;
}
};
Retrofit retrofit = new Retrofit.Builder(platform)
.baseUrl("http://example.com/")
.build();
assertThat(retrofit.callbackExecutor()).isSameAs(executor);
}
@Test public void callbackExecutorPropagated() {
Executor executor = mock(Executor.class);
Retrofit retrofit = new Retrofit.Builder()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册