jenzz/RxAppState

Event AppState.FOREGROUND is not called on initialisation

Closed this issue · 7 comments

Hi,

Thank you for this library, this is super useful !
I was wondering if there was a reason behind the fact that AppState.FOREGROUND is not send after the initialisation.

In AppStateRecognizer the method onAppDidEnterForeground() is called only of the current state is AppState.BACKGROUND which is not the case immediately since the value is initialised with null.

One of my managers is registering with the asObservable() method but does not receive the first value which is expected to launch a polling method.

Many thanks

jenzz commented

Hey @Christophe668.

That was a deliberate design decision to not (!) emit a FOREGROUND event upon subscription.
Semantically, the app state did not really change because the app is already in the foreground.

Correct me if I'm wrong, but there should be nothing stopping you from manually kicking off your polling method as an initial launch?
Pseudo code:

public final class AppStateManager {

    private final Application app;

    public AppStateManager(Application app) {
        this.app = app;
    }

    public void init() {
      RxAppState.monitor(app).subscribe(new Action1<AppState>() {
        @Override
        public void call(AppState appState) {
          switch (appState) {
            case FOREGROUND:
              handleForeground();
              break;
            case BACKGROUND:
              handleBackground();
              break;
          }
        }
      });
      // manually kicking off initial foreground handling
      handleForeground();
    }

    private void handleForeground() { /* ... */ }
    private void handleBackground() { /* ... */ }
}
jenzz commented

The fact that AppStateRecognizer is missing a default AppState value is indeed a bug.
I have created a new issue for that.

I'll push out an update as soon as I've come up with a sensible solution for it.
Any suggestions are welcome.

Hi Jenzz,
Sorry for this late reply, indeed I understant this choice. It was for a particular use case but I manage to handle that in a similar way with Rx.

Thank you for your feedback !

Hi,

Thanks @jenzz for such a useful library.

Sorry for bringing this closed issue up again, but I find the suggestion of manually kicking the foreground handling on first launch not suitable for some cases.

The Application.onCreate() method is not only called when the user effectively launches the app opening an Activity for the first time, but it may also be called from a Service or an Intent that doesn't necessarily open the app but it just may do some background work. Then, if I understood you correctly, the assumption that I may call some handleForeground() method right after subscribing to the Observable<AppState> is not correct when doing it from the Application.onCreate() method, but only when I actually subscribe from an Activity.

Inspecting your code, in AppStateRecognizer, as @Christophe668 says, onAppDidEnterForeground() is called only if the current state is AppState.BACKGROUND. But it sounds pretty reasonable to me to call it also when isFirstLaunch is true in the onActivityStarted callback, since at that point you are sure that an activity has been started and the app has been launched for the first time, so for sure it's previous state was BACKGROUND and the new one is FOREGROUND and then my understanding is that it should be notified. So the implementation of that callback could be something like:

@Override
public void onActivityStarted(Activity activity) {
  if (isFirstLaunch.compareAndSet(true, false)) {
    onAppDidEnterForeground();
    return;
  }

  if (appState == BACKGROUND) {
    onAppDidEnterForeground();
  }
}

Thanks so much for your attention.

jenzz commented

@mbarrben, you are making a good point there.

I have re-opened this issue and will try to include a fix in the next update. Your suggestion sounds reasonable.

I have a similar case to @mbarrben and that fix would be really useful for me too.
Thanks :)

jenzz commented

I have just merged PR #9 by @mbarrben which fixes / changes this behaviour.

It will be part of release v1.2.0.