diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 26b7021929ed3..05bf0b73a9f81 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -47,10 +47,14 @@ enum AppLifecycleState { /// in the foreground inactive state. Apps transition to this state when in /// a phone call, responding to a TouchID request, when entering the app /// switcher or the control center, or when the UIViewController hosting the - /// Flutter app is transitioning. Apps in this state should assume that they - /// may be [paused] at any time. - /// - /// On Android, this state is currently unused. + /// Flutter app is transitioning. + /// + /// On Android, this corresponds to an app or the Flutter host view running + /// in the foreground inactive state. Apps transition to this state when + /// another activity is focused, such as a split-screen app, a phone call, + /// a picture-in-picture app, a system dialog, or another window. + /// + /// Apps in this state should assume that they may be [paused] at any time. inactive, /// The application is not currently visible to the user, not responding to diff --git a/shell/platform/android/io/flutter/app/FlutterActivity.java b/shell/platform/android/io/flutter/app/FlutterActivity.java index f01e85a1a2437..ab566c485a1e6 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivity.java +++ b/shell/platform/android/io/flutter/app/FlutterActivity.java @@ -99,6 +99,12 @@ public void onBackPressed() { super.onBackPressed(); } } + + @Override + protected void onStop() { + eventDelegate.onStop(); + super.onStop(); + } @Override protected void onPause() { diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index 9de35c4b480a7..1c880d7e46987 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -218,6 +218,11 @@ public void onResume() { } } + @Override + public void onStop() { + flutterView.onStop(); + } + @Override public void onPostResume() { if (flutterView != null) { diff --git a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java index 98a3a1016c85f..8d8eb422aa338 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityEvents.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityEvents.java @@ -54,6 +54,11 @@ public interface FlutterActivityEvents */ void onDestroy(); + /** + * @see android.app.Activity#onStop() + */ + void onStop(); + /** * Invoked when the activity has detected the user's press of the back key. * diff --git a/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java index cc8325df974e8..92ecb2226a4e4 100644 --- a/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java @@ -98,6 +98,13 @@ public void onBackPressed() { } } + @Override + protected void onStop() { + eventDelegate.onStop(); + super.onStop(); + } + + @Override protected void onPause() { super.onPause(); diff --git a/shell/platform/android/io/flutter/view/FlutterNativeView.java b/shell/platform/android/io/flutter/view/FlutterNativeView.java index 034a86d09d91f..7b843878143f0 100644 --- a/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -128,7 +128,14 @@ private void attach(FlutterNativeView view) { // Called by native to send us a platform message. private void handlePlatformMessage(final String channel, byte[] message, final int replyId) { - assertAttached(); + // The platform may not be attached immediately in certain cases where a new bundle is run - + // the native view is created in a separate thread. This mostly happens when the app restarts in dev + // mode when switching into split-screen mode. Preventing app restarts on layout and density + // changes will prevent this, and afterwards this can be changed back to an assert. + if (!isAttached()) { + Log.d(TAG, "PlatformView is not attached"); + return; + } BinaryMessageHandler handler = mMessageHandlers.get(channel); if (handler != null) { try { diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index 6b8f6b47f6fd4..38b0df20b96c2 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -267,7 +267,7 @@ public void addActivityLifecycleListener(ActivityLifecycleListener listener) { } public void onPause() { - mFlutterLifecycleChannel.send("AppLifecycleState.paused"); + mFlutterLifecycleChannel.send("AppLifecycleState.inactive"); } public void onPostResume() { @@ -278,7 +278,7 @@ public void onPostResume() { } public void onStop() { - mFlutterLifecycleChannel.send("AppLifecycleState.suspending"); + mFlutterLifecycleChannel.send("AppLifecycleState.paused"); } public void onMemoryPressure() {