Enabling the host application to control the timing of attaching the |FlutterView| to the engine (flutter/engine#43595)
In the add-to-app scenario where multiple FlutterViews share the same FlutterEngine, the host application desires to determine the timing of attaching the FlutterView to the engine, for example, during the `onResume` instead of the `onCreateView`. As an example, consider the following scenario: A native page contains multiple tabs, and each tab is a FlutterFragment. During initialization, FlutterFragments of different tabs are created almost simultaneously, but only the one that needs to be displayed currently requires attachment to the engine, while the others need to be attached only when they receive the |onResume| callback. Partial fix: https://github.com/flutter/flutter/issues/130235 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
@@ -1407,6 +1407,19 @@ public class FlutterActivity extends Activity
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to automatically attach the {@link FlutterView} to the engine.
|
||||
*
|
||||
* <p>Returning {@code false} means that the task of attaching the {@link FlutterView} to the
|
||||
* engine will be taken over by the host application.
|
||||
*
|
||||
* <p>Defaults to {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean attachToEngineAutomatically() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean popSystemNavigator() {
|
||||
// Hook for subclass. No-op if returns false.
|
||||
|
||||
@@ -390,8 +390,10 @@ import java.util.List;
|
||||
// Add listener to be notified when Flutter renders its first frame.
|
||||
flutterView.addOnFirstFrameRenderedListener(flutterUiDisplayListener);
|
||||
|
||||
Log.v(TAG, "Attaching FlutterEngine to FlutterView.");
|
||||
flutterView.attachToFlutterEngine(flutterEngine);
|
||||
if (host.attachToEngineAutomatically()) {
|
||||
Log.v(TAG, "Attaching FlutterEngine to FlutterView.");
|
||||
flutterView.attachToFlutterEngine(flutterEngine);
|
||||
}
|
||||
flutterView.setId(flutterViewId);
|
||||
|
||||
if (shouldDelayFirstAndroidViewDraw) {
|
||||
@@ -1171,5 +1173,17 @@ import java.util.List;
|
||||
* while return {@code true} means the engine dispatches these events.
|
||||
*/
|
||||
boolean shouldDispatchAppLifecycleState();
|
||||
|
||||
/**
|
||||
* Whether to automatically attach the {@link FlutterView} to the engine.
|
||||
*
|
||||
* <p>In the add-to-app scenario where multiple {@link FlutterView} share the same {@link
|
||||
* FlutterEngine}, the host application desires to determine the timing of attaching the {@link
|
||||
* FlutterView} to the engine, for example, during the {@code onResume} instead of the {@code
|
||||
* onCreateView}.
|
||||
*
|
||||
* <p>Defaults to {@code true}.
|
||||
*/
|
||||
boolean attachToEngineAutomatically();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1645,6 +1645,19 @@ public class FlutterFragment extends Fragment
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to automatically attach the {@link FlutterView} to the engine.
|
||||
*
|
||||
* <p>Returning {@code false} means that the task of attaching the {@link FlutterView} to the
|
||||
* engine will be taken over by the host application.
|
||||
*
|
||||
* <p>Defaults to {@code true}.
|
||||
*/
|
||||
@Override
|
||||
public boolean attachToEngineAutomatically() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
||||
@@ -2,9 +2,11 @@ package io.flutter.embedding.android;
|
||||
|
||||
import static android.content.ComponentCallbacks2.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNotNull;
|
||||
@@ -88,6 +90,7 @@ public class FlutterActivityAndFragmentDelegateTest {
|
||||
when(mockHost.shouldHandleDeeplinking()).thenReturn(false);
|
||||
when(mockHost.shouldDestroyEngineWithHost()).thenReturn(true);
|
||||
when(mockHost.shouldDispatchAppLifecycleState()).thenReturn(true);
|
||||
when(mockHost.attachToEngineAutomatically()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1241,6 +1244,31 @@ public class FlutterActivityAndFragmentDelegateTest {
|
||||
assertEquals(engineUnderTest, mockFlutterEngine);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itDoesAttachFlutterViewToEngine() {
|
||||
// ---- Test setup ----
|
||||
// Create the real object that we're testing.
|
||||
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
|
||||
delegate.onAttach(ctx);
|
||||
delegate.onCreateView(null, null, null, 0, true);
|
||||
|
||||
// --- Execute the behavior under test ---
|
||||
assertTrue(delegate.flutterView.isAttachedToFlutterEngine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itDoesNotAttachFlutterViewToEngine() {
|
||||
// ---- Test setup ----
|
||||
// Create the real object that we're testing.
|
||||
when(mockHost.attachToEngineAutomatically()).thenReturn(false);
|
||||
FlutterActivityAndFragmentDelegate delegate = new FlutterActivityAndFragmentDelegate(mockHost);
|
||||
delegate.onAttach(ctx);
|
||||
delegate.onCreateView(null, null, null, 0, true);
|
||||
|
||||
// --- Execute the behavior under test ---
|
||||
assertFalse(delegate.flutterView.isAttachedToFlutterEngine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mock {@link io.flutter.embedding.engine.FlutterEngine}.
|
||||
*
|
||||
|
||||
@@ -389,6 +389,11 @@ public class FlutterAndroidComponentTest {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attachToEngineAutomatically() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFlutterSurfaceViewCreated(@NonNull FlutterSurfaceView flutterSurfaceView) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user