From 6697656520c99f23c9b8523cc686b8c34818604a Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Wed, 1 May 2019 17:20:43 -0700 Subject: [PATCH 1/2] Allow FlutterEngine to be used on back-to-back screens (#31264). --- .../embedding/android/FlutterFragment.java | 44 +++++++++++-------- .../embedding/android/FlutterView.java | 2 +- .../engine/renderer/FlutterRenderer.java | 9 ++++ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index e8d2cc60cae65..a8b0c3bc06b65 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -378,25 +378,6 @@ protected FlutterEngine createFlutterEngine(@NonNull Context context) { public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { flutterView = new FlutterView(getContext(), getRenderMode(), getTransparencyMode()); flutterView.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener); - - // We post() the code that attaches the FlutterEngine to our FlutterView because there is - // some kind of blocking logic on the native side when the surface is connected. That lag - // causes launching Activitys to wait a second or two before launching. By post()'ing this - // behavior we are able to move this blocking logic to after the Activity's launch. - // TODO(mattcarroll): figure out how to avoid blocking the MAIN thread when connecting a surface - new Handler().post(new Runnable() { - @Override - public void run() { - flutterView.attachToFlutterEngine(flutterEngine); - - // TODO(mattcarroll): the following call should exist here, but the plugin system needs to be revamped. - // The existing attach() method does not know how to handle this kind of FlutterView. - //flutterEngine.getPluginRegistry().attach(this, getActivity()); - - doInitialFlutterViewRun(); - } - }); - return flutterView; } @@ -486,9 +467,34 @@ protected FlutterView.TransparencyMode getTransparencyMode() { return FlutterView.TransparencyMode.valueOf(transparencyModeName); } + @Override + public void onStart() { + super.onStart(); + Log.d(TAG, "onStart()"); + + // We post() the code that attaches the FlutterEngine to our FlutterView because there is + // some kind of blocking logic on the native side when the surface is connected. That lag + // causes launching Activitys to wait a second or two before launching. By post()'ing this + // behavior we are able to move this blocking logic to after the Activity's launch. + // TODO(mattcarroll): figure out how to avoid blocking the MAIN thread when connecting a surface + new Handler().post(new Runnable() { + @Override + public void run() { + flutterView.attachToFlutterEngine(flutterEngine); + + // TODO(mattcarroll): the following call should exist here, but the plugin system needs to be revamped. + // The existing attach() method does not know how to handle this kind of FlutterView. + //flutterEngine.getPluginRegistry().attach(this, getActivity()); + + doInitialFlutterViewRun(); + } + }); + } + @Override public void onResume() { super.onResume(); + Log.d(TAG, "onResume()"); flutterEngine.getLifecycleChannel().appIsResumed(); } diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/shell/platform/android/io/flutter/embedding/android/FlutterView.java index 21b40575a7280..df3e9d93065de 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -547,7 +547,7 @@ public void detachFromFlutterEngine() { } private boolean isAttachedToFlutterEngine() { - return flutterEngine != null; + return flutterEngine != null && flutterEngine.getRenderer().isAttachedTo(renderSurface); } /** diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 2dfac4c67e826..3be1f8bc3b169 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -10,6 +10,7 @@ import android.os.Build; import android.os.Handler; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.view.Surface; import java.nio.ByteBuffer; @@ -43,6 +44,14 @@ public FlutterRenderer(@NonNull FlutterJNI flutterJNI) { this.flutterJNI = flutterJNI; } + /** + * Returns true if this {@code FlutterRenderer} is attached to the given {@link RenderSurface}, + * false otherwise. + */ + public boolean isAttachedTo(@NonNull RenderSurface renderSurface) { + return this.renderSurface == renderSurface; + } + public void attachToRenderSurface(@NonNull RenderSurface renderSurface) { // TODO(mattcarroll): determine desired behavior when attaching to an already attached renderer if (this.renderSurface != null) { From 7f3773c8a9cb7abddac369f618e3729a16eb85c6 Mon Sep 17 00:00:00 2001 From: Matt Carroll Date: Thu, 2 May 2019 12:38:02 -0700 Subject: [PATCH 2/2] Moved FlutterView/FlutterEngine detachment to FlutterFragment's onStop(). --- .../android/io/flutter/embedding/android/FlutterFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java index a8b0c3bc06b65..5b025423ad010 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java @@ -523,6 +523,7 @@ public void onStop() { super.onStop(); Log.d(TAG, "onStop()"); flutterEngine.getLifecycleChannel().appIsPaused(); + flutterView.detachFromFlutterEngine(); } @Override @@ -530,7 +531,6 @@ public void onDestroyView() { super.onDestroyView(); Log.d(TAG, "onDestroyView()"); flutterView.removeOnFirstFrameRenderedListener(onFirstFrameRenderedListener); - flutterView.detachFromFlutterEngine(); } @Override