community icon indicating copy to clipboard operation
community copied to clipboard

Android Lifecycle convergence

Open RobertFlatt opened this issue 3 years ago • 2 comments
trafficstars

Maintainer merge checklist

  • [x] Title is descriptive/clear for inclusion in release notes.
  • [x] Applied a Component: xxx label.
  • [ ] Applied the api-deprecation or api-break label.
  • [ ] Applied the release-highlight label 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, versionchanged as needed.

RobertFlatt avatar Aug 30 '22 01:08 RobertFlatt

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:

    1. Back Gesture/Button | App: stop | Android : pause |
    1. on_pause False | App : stop | Android : no change |
    1. app.stop() | App: stop | Android : no change |
    1. app.pause() | App : N/A | Android : N/A |
    1. Android sleep->destroy | App : sleep | Android : destroyed |
    1. 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 the return statement in on_pause there 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.

RobertFlatt avatar Aug 30 '22 01:08 RobertFlatt

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.

RobertFlatt avatar Sep 21 '22 00:09 RobertFlatt

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! 😃

misl6 avatar Oct 01 '22 09:10 misl6

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

RobertFlatt avatar Oct 02 '22 00:10 RobertFlatt