Skip to content

Better way to handle subscribing on non-UI thread #269

@exloong

Description

@exloong

Android asks to call lifecycle.addObserver(observer); on the main thread, and here are the source code in LifecycleEventsObservable which I think have issues and can be better handled.

@Override protected void subscribeActual(Observer<? super Event> observer) {
    ArchLifecycleObserver archObserver =
        new ArchLifecycleObserver(lifecycle, observer, eventsObservable);
    observer.onSubscribe(archObserver);
    if (!isMainThread()) {
      observer.onError(
          new IllegalStateException("Lifecycles can only be bound to on the main thread!"));
      return;
    }
    lifecycle.addObserver(archObserver);
    if (archObserver.isDisposed()) {
      lifecycle.removeObserver(archObserver);
    }
  }

Issue:
Sending an error to Observable(and other equivalents such as Completable, Maybe and so on, I'll use Observable to represent them all) means it can be handled accordingly at runtime, but subscribe on a wrong thread cannot and shouldn't be handled at runtime. In this way, the errors are hide and redirected to a wrong channel. And it is not well mentioned in the documentation either, people can come across this issue accidentally without noticing (as someone might choose to swallow any errors from Obserable).

Possible solutions:

  1. Mention all subscribe() should be called in main thread in documentation and add @MainThread to all subscribe() methods in ObservableSubscribeProxy class.

  2. (Personally preferred) Switch to main thread inside of subscribeActual when calling lifecycle.addObserver(archObserver); and lifecycle.removeObserver(archObserver);

  3. Throw IllegalStateException in subscribeActual() directly and crash the app, giving enough notice while debugging.

If you think it is really an issue and one of the solutions works, I am more than happy to implement them and create a pull request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions