community
community copied to clipboard
Android Lifecycle convergence
Maintainer merge checklist
- [x] Title is descriptive/clear for inclusion in release notes.
- [x] Applied a
Component: xxxlabel. - [ ] Applied the
api-deprecationorapi-breaklabel. - [ ] Applied the
release-highlightlabel to be highlighted in release notes. - [x] Added to the milestone version it was merged into.
- [ ] Unittests are included in PR.
- [x] Properly documented, including
versionadded,versionchangedas needed.
Executive Summary
On a mobile device (unlike a desktop) the Kivy Lifecycle is an abstraction of a lifecycle implemented in the OS. The Kivy and OS state machines muct remain synchronized to avoid ambigious states.
This PR addresses differences between these state machines on Android, it may be a template for extending these observations to iOS.
Issues
On Android the cases where the Kivy state machine diverges from the Android state machine are:
-
- Back Gesture/Button | App: stop | Android : pause |
-
- on_pause False | App : stop | Android : no change |
-
- app.stop() | App: stop | Android : no change |
-
- app.pause() | App : N/A | Android : N/A |
-
- Android sleep->destroy | App : sleep | Android : destroyed |
-
- Android destroy app | App: service quit | Android : service no change |
In this PR we address issues i thru iv. Issues v and vi are not Kivy issues.
Discussion and proposed changes
- Cases i-iii) In general the Kivy state machine follows the Android state machine via events from SDL2. However in these three cases Kivy sets its own state without informing Android. The cases are addressed by replacing Kivy state changes with calls to Android telling it to change state. The Android state change will in turn tell Kivy to change state via SDL2.
Both Android api calls used in this PR are available on all current p4a supported Android versions. https://developer.android.com/reference/android/app/Activity#moveTaskToBack(boolean) https://developer.android.com/reference/android/app/Activity#finishAndRemoveTask()
-
Case iv) is currently this is not implemented in Kivy, it is implemented in this PR (in the same manner as the first 3 cases) for completeness.
-
Case v) Is not implemented in SDL2 https://github.com/libsdl-org/SDL/issues/3297 . Hence Kivy fails to issue an 'on_stop' - this is documented. There are no other known side effects. If it is an issue, it is an SDL2 issue.
-
Case vi) The maximum lifetime of a Kivy Android service is the lifetime of the Kivy App (that is until the app is killed, not until the app is paused). This behavior is not changed by this PR. However this is not the default behavior of a service in a Java Android app. If it is an issue, it is a p4a issue.
-
Case ii Revisited) The case is addressed in this PR, but I really think the 'on_pause return' feature should be removed. The utility is unclear to me (
self.stop()exists and is more intuative) and there is an unfortunate side effect. As designed, if a user omits thereturnstatement inon_pausethere will be no effect on desktop execution (on_pause is not called) but on mobile the app will correctly dissappear from the screen and the task list. The connection between a simple coding error and the app behavior is not intuative. This PR logs this event, and corrects an ambiguity in the comment/documentation. If there is interest in removing the functionality I can create a PR for this.
but I really think the 'on_pause return' feature should be removed.
it will need to be deprecated at first, and then removed in 2/3 releases
Faced with inertia I'm less enthusiastic!
Its really about cleaning up some fuzzy design, not a bug. So not something I'd fight hard for.
A quick search finds 3 cases:
kivy-master>grep -R \'on_pause\'
kivy/core/window/window_sdl2.py: elif not app.dispatch('on_pause'):
kivy/core/window/window_sdl2.py: elif not app.dispatch('on_pause'):
kivy/support.py: if app.dispatch('on_pause'):
I could add a Logger.warning message in the return False case. The return True case is a NOP and of course very common, a warning in that case would generate a storm of confusion.
but I really think the 'on_pause return' feature should be removed.
it will need to be deprecated at first, and then removed in 2/3 releases
Faced with inertia I'm less enthusiastic!
Its really about cleaning up some fuzzy design, not a bug. So not something I'd fight hard for.
A quick search finds 3 cases:
kivy-master>grep -R \'on_pause\' kivy/core/window/window_sdl2.py: elif not app.dispatch('on_pause'): kivy/core/window/window_sdl2.py: elif not app.dispatch('on_pause'): kivy/support.py: if app.dispatch('on_pause'):I could add a Logger.warning message in the return False case. The return True case is a NOP and of course very common, a warning in that case would generate a storm of confusion.
Let's open an issue to keep it tracked! 😃
For anybody reading this in my future, it turns out issue iv) 'service lifetime' has previously been fixed https://github.com/kivy/python-for-android/pull/2401