Skip to content

Commit

Permalink
Fix AndroidSchedulers to create an instance using hook only once.
Browse files Browse the repository at this point in the history
Previously we were asking the hook for an instance every time `mainThread()` was called. This not only impacted performance, but also broke the contract the that hook was a factory–instead requiring that it behave like a thread-safe, lazily-initialized instance cache.

If for whatever reason you do need to change the instance over time, return a scheduler instance which delegates to another and allows swapping out the delegate.
  • Loading branch information
JakeWharton committed May 2, 2016
1 parent aeb3ae5 commit ce9c29a
Showing 1 changed file with 13 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,28 @@
import android.os.Looper;
import rx.Scheduler;
import rx.android.plugins.RxAndroidPlugins;
import rx.android.plugins.RxAndroidSchedulersHook;

/** Android-specific Schedulers. */
public final class AndroidSchedulers {
private static final AndroidSchedulers INSTANCE = new AndroidSchedulers();

private final Scheduler mainThreadScheduler;

private AndroidSchedulers() {
throw new AssertionError("No instances");
}
RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();

// See https://github.com/ReactiveX/RxAndroid/issues/238
// https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
private static class MainThreadSchedulerHolder {
static final Scheduler MAIN_THREAD_SCHEDULER = new LooperScheduler(Looper.getMainLooper());
Scheduler main = hook.getMainThreadScheduler();
if (main != null) {
mainThreadScheduler = main;
} else {
mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());
}
}

/** A {@link Scheduler} which executes actions on the Android UI thread. */
public static Scheduler mainThread() {
Scheduler scheduler =
RxAndroidPlugins.getInstance().getSchedulersHook().getMainThreadScheduler();
return scheduler != null ? scheduler : MainThreadSchedulerHolder.MAIN_THREAD_SCHEDULER;
return INSTANCE.mainThreadScheduler;
}

/** A {@link Scheduler} which executes actions on {@code looper}. */
Expand Down

0 comments on commit ce9c29a

Please sign in to comment.