From 03e3c8bc39eecfbc1900792e4b3ba415fef10d0e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 12 Apr 2018 11:00:31 -0700 Subject: [PATCH] Do not pause rendering when android activity loses focus (flutter/engine#4848) * do not pause rendering when android view loses focus --- engine/src/flutter/lib/ui/window.dart | 10 +++++++--- .../android/io/flutter/app/FlutterActivity.java | 6 ++++++ .../io/flutter/app/FlutterActivityDelegate.java | 5 +++++ .../android/io/flutter/app/FlutterActivityEvents.java | 5 +++++ .../io/flutter/app/FlutterFragmentActivity.java | 7 +++++++ .../android/io/flutter/view/FlutterNativeView.java | 9 ++++++++- .../platform/android/io/flutter/view/FlutterView.java | 4 ++-- 7 files changed, 40 insertions(+), 6 deletions(-) diff --git a/engine/src/flutter/lib/ui/window.dart b/engine/src/flutter/lib/ui/window.dart index 26b7021929e..05bf0b73a9f 100644 --- a/engine/src/flutter/lib/ui/window.dart +++ b/engine/src/flutter/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. + /// Flutter app is transitioning. /// - /// On Android, this state is currently unused. + /// 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/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivity.java b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivity.java index f01e85a1a24..ab566c485a1 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivity.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivity.java @@ -99,6 +99,12 @@ public class FlutterActivity extends Activity implements FlutterView.Provider, P super.onBackPressed(); } } + + @Override + protected void onStop() { + eventDelegate.onStop(); + super.onStop(); + } @Override protected void onPause() { diff --git a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index 9de35c4b480..1c880d7e469 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -218,6 +218,11 @@ public final class FlutterActivityDelegate } } + @Override + public void onStop() { + flutterView.onStop(); + } + @Override public void onPostResume() { if (flutterView != null) { diff --git a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityEvents.java b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityEvents.java index 98a3a1016c8..8d8eb422aa3 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterActivityEvents.java +++ b/engine/src/flutter/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/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java index cc8325df974..92ecb2226a4 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/app/FlutterFragmentActivity.java @@ -98,6 +98,13 @@ public class FlutterFragmentActivity } } + @Override + protected void onStop() { + eventDelegate.onStop(); + super.onStop(); + } + + @Override protected void onPause() { super.onPause(); diff --git a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java index 034a86d09d9..7b843878143 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterNativeView.java @@ -128,7 +128,14 @@ public class FlutterNativeView implements BinaryMessenger { // 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/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java index 6b8f6b47f6f..38b0df20b96 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/view/FlutterView.java @@ -267,7 +267,7 @@ public class FlutterView extends SurfaceView } public void onPause() { - mFlutterLifecycleChannel.send("AppLifecycleState.paused"); + mFlutterLifecycleChannel.send("AppLifecycleState.inactive"); } public void onPostResume() { @@ -278,7 +278,7 @@ public class FlutterView extends SurfaceView } public void onStop() { - mFlutterLifecycleChannel.send("AppLifecycleState.suspending"); + mFlutterLifecycleChannel.send("AppLifecycleState.paused"); } public void onMemoryPressure() {