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
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() { /* ... */ }
}
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.
@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.