Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Android activity lifecycle management #1293

Closed
wants to merge 4 commits into from

Conversation

blaind
Copy link
Contributor

@blaind blaind commented Jan 23, 2021

This is a proof-of-concept implementation of Android activity lifecycles into bevy_winit crate.

For background, see:

Various comments:

  • Now, this code probably messes up winit crate for other platforms than android, how to implement android-specific parts properly?
  • Winit would require upstream patches. So far, it seems that winit events do not align with Android lifecycle very well. Winit mostly handles resume/suspended states, but in addition to these android has also the window lost states
  • Current winit patches: rust-windowing/winit@master...blaind:master
  • The code should be simplified
  • This has been tested only on one Android phone with one operating system, are the event flows similar in all Android versions?

So far, this handles the following cases:

  • Starting up an app in background (when running cargo apk run ...)
  • Clicking home button when activity is running
  • Resuming to the activity
  • Handling screen locking and resume correctly

Also, SaveInstanceState and the accompanying resume state (?) need to be handled.

Various logs of lifecycle eventsLog of lifecycle events reported by android (added println! statement in winit crate)

// first startup
01-23 19:26:35.358 14645 14696 I RustStdoutStderr: ndk_glue event: Start
01-23 19:26:35.358 14645 14696 I RustStdoutStderr: ndk_glue event: Resume
01-23 19:26:35.895 14645 14696 I RustStdoutStderr: ndk_glue event: InputQueueCreated
01-23 19:26:35.911 14645 14696 I RustStdoutStderr: ndk_glue event: WindowCreated
01-23 19:26:35.926 14645 14696 I RustStdoutStderr: ndk_glue event: WindowResized
01-23 19:26:35.940 14645 14696 I RustStdoutStderr: ndk_glue event: ContentRectChanged
01-23 19:26:35.972 14645 14696 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded
01-23 19:26:35.990 14645 14696 I RustStdoutStderr: ndk_glue event: WindowHasFocus

// pressing home button
01-23 19:26:42.530 14645 14696 I RustStdoutStderr: ndk_glue event: Pause
01-23 19:26:42.547 14645 14696 I RustStdoutStderr: ndk_glue event: WindowLostFocus
01-23 19:26:42.574 14645 14696 I RustStdoutStderr: ndk_glue event: Stop
01-23 19:26:42.580 14645 14696 I RustStdoutStderr: ndk_glue event: SaveInstanceState
01-23 19:26:42.613 14645 14696 I RustStdoutStderr: ndk_glue event: WindowDestroyed

// opening the activity back
01-23 19:27:11.866 14645 14696 I RustStdoutStderr: ndk_glue event: Start
01-23 19:27:11.867 14645 14696 I RustStdoutStderr: ndk_glue event: Resume
01-23 19:27:11.946 14645 14696 I RustStdoutStderr: ndk_glue event: WindowCreated
01-23 19:27:11.963 14645 14696 I RustStdoutStderr: ndk_glue event: WindowResized
01-23 19:27:11.981 14645 14696 I RustStdoutStderr: ndk_glue event: WindowHasFocus
01-23 19:27:12.045 14645 14696 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded

// screenlock on
01-23 19:27:24.228 14645 14696 I RustStdoutStderr: ndk_glue event: Pause
01-23 19:27:24.228 14645 14696 I RustStdoutStderr: ndk_glue event: Stop
01-23 19:27:24.228 14645 14696 I RustStdoutStderr: ndk_glue event: SaveInstanceState
01-23 19:27:24.758 14645 14696 I RustStdoutStderr: ndk_glue event: WindowLostFocus

// screenlock back
01-23 19:27:39.680 14645 14696 I RustStdoutStderr: ndk_glue event: Start
01-23 19:27:39.680 14645 14696 I RustStdoutStderr: ndk_glue event: Resume

// rotating screen
01-23 19:29:00.263 15025 15051 I RustStdoutStderr: ndk_glue event: ConfigChanged
01-23 19:29:00.322 15025 15051 I RustStdoutStderr: ndk_glue event: WindowResized
01-23 19:29:00.341 15025 15051 I RustStdoutStderr: ndk_glue event: ContentRectChanged
01-23 19:29:00.376 15025 15051 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded
01-23 19:29:00.399 15025 15051 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded

// pulling top bar down
01-23 19:31:49.498 15537 15554 I RustStdoutStderr: ndk_glue event: WindowLostFocus
01-23 19:31:50.068 15537 15554 I RustStdoutStderr: ndk_glue event: WindowHasFocus

Log printed with various debug items in bevy crate as well:

// start activity
01-23 20:16:58.212 22561 22588 I RustStdoutStderr: ndk_glue event: Start
01-23 20:16:58.212 22561 22588 I RustStdoutStderr: ndk_glue event: Resume
01-23 20:16:58.212 22561 22588 I RustStdoutStderr: ndk_glue event: InputQueueCreated
01-23 20:16:58.212 22561 22588 I RustStdoutStderr: ndk_glue event: WindowCreated
01-23 20:16:58.212 22561 22588 I RustStdoutStderr: ndk_glue event: WindowResized
01-23 20:16:58.212 22561 22588 I RustStdoutStderr: runnable window event (running=NotInitialized), event: Resized(PhysicalSize { width: 1080, height: 2220 })
01-23 20:16:58.213 22561 22588 I RustStdoutStderr: ndk_glue event: ContentRectChanged
01-23 20:16:58.213 22561 22588 I RustStdoutStderr: ndk_glue event: WindowHasFocus
01-23 20:16:58.213 22561 22588 I RustStdoutStderr: runnable window event (running=NotInitialized), event: Focused(true)
01-23 20:16:58.213 22561 22588 I RustStdoutStderr: runnable: focused=true, running=NotInitialized
01-23 20:16:58.213 22561 22588 I RustStdoutStderr: runnable state change from NotInitialized to Running
01-23 20:16:58.734 22561 22588 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded

// home button
01-23 20:17:19.323 22561 22588 I RustStdoutStderr: ndk_glue event: Pause
01-23 20:17:19.323 22561 22588 I RustStdoutStderr: runnable state change from Running to WindowLost
01-23 20:17:19.327 22561 22588 I RustStdoutStderr: ndk_glue event: WindowLostFocus
01-23 20:17:19.327 22561 22588 I RustStdoutStderr: runnable window event (running=WindowLost), event: Focused(false)
01-23 20:17:19.327 22561 22588 I RustStdoutStderr: runnable: focused=false, running=WindowLost
01-23 20:17:19.354 22561 22588 I RustStdoutStderr: ndk_glue event: Stop
01-23 20:17:19.354 22561 22588 I RustStdoutStderr: ndk_glue event: SaveInstanceState
01-23 20:17:19.381 22561 22588 I RustStdoutStderr: ndk_glue event: WindowDestroyed
01-23 20:17:19.381 22561 22588 I RustStdoutStderr: runnable state change from WindowLost to WindowLost



// return to activity
01-23 20:17:31.825 22561 22588 I RustStdoutStderr: ndk_glue event: Start
01-23 20:17:31.830 22561 22588 I RustStdoutStderr: ndk_glue event: Resume
01-23 20:17:31.855 22561 22588 I RustStdoutStderr: ndk_glue event: WindowCreated
01-23 20:17:31.855 22561 22588 I RustStdoutStderr: ndk_glue event: WindowResized
01-23 20:17:31.856 22561 22588 I RustStdoutStderr: runnable window event (running=WindowLost), event: Resized(PhysicalSize { width: 1080, height: 2220 })
01-23 20:17:31.857 22561 22588 I RustStdoutStderr: ndk_glue event: WindowHasFocus
01-23 20:17:31.857 22561 22588 I RustStdoutStderr: runnable window event (running=WindowLost), event: Focused(true)
01-23 20:17:31.857 22561 22588 I RustStdoutStderr: runnable: focused=true, running=WindowLost
01-23 20:17:31.857 22561 22588 I RustStdoutStderr: runnable state change from WindowLost to WaitForWindow
01-23 20:17:31.896 22561 22588 I RustStdoutStderr: runnable state change from WaitForWindow to Running
01-23 20:17:31.920 22561 22588 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded


// pull top bar down and back up
01-23 20:17:40.581 22561 22588 I RustStdoutStderr: ndk_glue event: WindowLostFocus
01-23 20:17:40.581 22561 22588 I RustStdoutStderr: runnable window event (running=Running), event: Focused(false)
01-23 20:17:40.581 22561 22588 I RustStdoutStderr: runnable: focused=false, running=Running
01-23 20:17:40.976 22561 22588 I RustStdoutStderr: ndk_glue event: WindowHasFocus
01-23 20:17:40.976 22561 22588 I RustStdoutStderr: runnable window event (running=Running), event: Focused(true)
01-23 20:17:40.976 22561 22588 I RustStdoutStderr: runnable: focused=true, running=Running

// screen lock
01-23 20:18:00.012 22561 22588 I RustStdoutStderr: ndk_glue event: Pause
01-23 20:18:00.012 22561 22588 I RustStdoutStderr: runnable state change from Running to WindowLost
01-23 20:18:00.012 22561 22588 I RustStdoutStderr: ndk_glue event: Stop
01-23 20:18:00.012 22561 22588 I RustStdoutStderr: ndk_glue event: SaveInstanceState
01-23 20:18:00.461 22561 22588 I RustStdoutStderr: ndk_glue event: WindowLostFocus
01-23 20:18:00.461 22561 22588 I RustStdoutStderr: runnable window event (running=WindowLost), event: Focused(false)
01-23 20:18:00.461 22561 22588 I RustStdoutStderr: runnable: focused=false, running=WindowLost


// open screen lock
01-23 20:18:14.527 22561 22588 I RustStdoutStderr: ndk_glue event: Start
01-23 20:18:14.535 22561 22588 I RustStdoutStderr: ndk_glue event: Resume
01-23 20:18:14.569 22561 22588 I RustStdoutStderr: ndk_glue event: WindowCreated
01-23 20:18:14.570 22561 22588 I RustStdoutStderr: ndk_glue event: WindowResized
01-23 20:18:14.571 22561 22588 I RustStdoutStderr: runnable window event (running=WindowLost), event: Resized(PhysicalSize { width: 1080, height: 2220 })
01-23 20:18:14.589 22561 22588 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded
01-23 20:18:14.606 22561 22588 I RustStdoutStderr: ndk_glue event: WindowRedrawNeeded
01-23 20:18:14.667 22561 22588 I RustStdoutStderr: ndk_glue event: WindowHasFocus
01-23 20:18:14.667 22561 22588 I RustStdoutStderr: runnable window event (running=WindowLost), event: Focused(true)
01-23 20:18:14.667 22561 22588 I RustStdoutStderr: runnable: focused=true, running=WindowLost
01-23 20:18:14.667 22561 22588 I RustStdoutStderr: runnable state change from WindowLost to WaitForWindow
01-23 20:18:14.723 22561 22588 I RustStdoutStderr: runnable state change from WaitForWindow to Running

This was referenced Jan 23, 2021
@cart
Copy link
Member

cart commented Jan 23, 2021

I'm not an expert on android app development, so I can't comment directly on the "proper way to handle android lifecycle events in winit" side of things without doing more research.

But I really appreciate that you're digging in to this. Thanks!

@blaind blaind marked this pull request as draft January 30, 2021 20:29
@alice-i-cecile alice-i-cecile added O-Android Specific to the Android mobile operating system help wanted labels Feb 17, 2021
Base automatically changed from master to main February 19, 2021 20:44
@cart cart added the S-Pre-Relicense This PR was made before Bevy added the Apache license. Cannot be merged or used for other work label Jul 23, 2021
@DJMcNab DJMcNab removed the S-Pre-Relicense This PR was made before Bevy added the Apache license. Cannot be merged or used for other work label Aug 7, 2021
@alice-i-cecile alice-i-cecile added the X-Controversial There is active debate or serious implications around merging this PR label Apr 22, 2022
@blaind
Copy link
Contributor Author

blaind commented Sep 4, 2022

This has progressed in other issues (referenced in #86, I'll close)

@blaind blaind closed this Sep 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-Android Specific to the Android mobile operating system X-Controversial There is active debate or serious implications around merging this PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants