Summary
React Native currently exposes Android AppState in a way that can make
Activity.onPause() indistinguishable from a real app background transition.
This is documented behavior today, but it can be surprising in Android system
flows such as autofill credential pickers and password managers.
Context
On Android, AppState background can be emitted when another Activity takes
focus, including temporary system activities such as autofill credential pickers.
This behavior was recently clarified in:
A related historical issue is:
Problem
For many app developers, AppState background -> active is treated as "the
user left the app and returned". Apps often use this transition to refetch data,
refresh auth state, or reset screens.
However, Android may pause the host Activity for temporary system flows where
the app is still visually part of the user flow. One concrete example is:
- A login screen has username/password
TextInputs with Android autofill
enabled.
- The user taps a saved credential from Google Password Manager / Autofill.
- React Native emits
AppState active -> background -> active.
- App code listening for
active refetches data and remounts the login form.
- Android loses the autofill target before credentials are filled.
The app can avoid this by not doing destructive work on every active event, but
the underlying API still collapses several Android lifecycle concepts into one
state.
Question / Proposal
Should React Native expose a more precise Android lifecycle signal, separate from
AppState?
Possible directions:
- Keep
AppState behavior unchanged, but expose an Android-only Activity/host
lifecycle event such as resumed, paused, and possibly stopped.
- Add a separate API, for example
ActivityState, for apps that need Android
Activity lifecycle semantics.
- Reconsider whether Android
AppState.background should be based on a lifecycle
signal closer to "not visible" rather than "paused", while accounting for
backwards compatibility.
- Keep the current API and rely only on documentation.
The goal is not to special-case autofill or password managers. The broader issue
is that Android Activity pause and "app truly backgrounded" are different
concepts, but React Native currently exposes them through the same high-level
AppState transition.
Why this matters
A more precise signal would let apps distinguish:
- user actually left the app;
- temporary Android system UI / credential picker / permission flow;
- loss of focus;
- Activity pause without the same product meaning as a full app background.
This would help apps avoid fragile heuristics around AppState while preserving
the existing documented behavior for current users.
Contribution
If maintainers think one of these directions is appropriate, I would be happy to
help prototype and submit the implementation.
Summary
React Native currently exposes Android
AppStatein a way that can makeActivity.onPause()indistinguishable from a real app background transition.This is documented behavior today, but it can be surprising in Android system
flows such as autofill credential pickers and password managers.
Context
On Android,
AppStatebackgroundcan be emitted when anotherActivitytakesfocus, including temporary system activities such as autofill credential pickers.
This behavior was recently clarified in:
A related historical issue is:
Problem
For many app developers,
AppStatebackground -> activeis treated as "theuser left the app and returned". Apps often use this transition to refetch data,
refresh auth state, or reset screens.
However, Android may pause the host
Activityfor temporary system flows wherethe app is still visually part of the user flow. One concrete example is:
TextInputs with Android autofillenabled.
AppStateactive -> background -> active.activerefetches data and remounts the login form.The app can avoid this by not doing destructive work on every
activeevent, butthe underlying API still collapses several Android lifecycle concepts into one
state.
Question / Proposal
Should React Native expose a more precise Android lifecycle signal, separate from
AppState?Possible directions:
AppStatebehavior unchanged, but expose an Android-only Activity/hostlifecycle event such as
resumed,paused, and possiblystopped.ActivityState, for apps that need AndroidActivity lifecycle semantics.
AppState.backgroundshould be based on a lifecyclesignal closer to "not visible" rather than "paused", while accounting for
backwards compatibility.
The goal is not to special-case autofill or password managers. The broader issue
is that Android
Activitypause and "app truly backgrounded" are differentconcepts, but React Native currently exposes them through the same high-level
AppStatetransition.Why this matters
A more precise signal would let apps distinguish:
This would help apps avoid fragile heuristics around
AppStatewhile preservingthe existing documented behavior for current users.
Contribution
If maintainers think one of these directions is appropriate, I would be happy to
help prototype and submit the implementation.