未验证 提交 fad9ae8e 编写于 作者: X xster 提交者: GitHub

Load FlutterLoader when creating FlutterEngineGroup (#23980)

上级 f6280f26
......@@ -8,7 +8,9 @@ import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.FlutterInjector;
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint;
import io.flutter.embedding.engine.loader.FlutterLoader;
import java.util.ArrayList;
import java.util.List;
......@@ -25,6 +27,9 @@ import java.util.List;
* io.flutter.embedding.engine.FlutterEngine}s are created, resources from an existing living {@link
* io.flutter.embedding.engine.FlutterEngine} is re-used.
*
* <p>The shared resources are kept until the last surviving {@link
* io.flutter.embedding.engine.FlutterEngine} is destroyed.
*
* <p>Deleting a FlutterEngineGroup doesn't invalidate its existing {@link
* io.flutter.embedding.engine.FlutterEngine}s, but it eliminates the possibility to create more
* {@link io.flutter.embedding.engine.FlutterEngine}s in that group.
......@@ -33,6 +38,23 @@ public class FlutterEngineGroup {
/* package */ @VisibleForTesting final List<FlutterEngine> activeEngines = new ArrayList<>();
/** Create a FlutterEngineGroup whose child engines will share resources. */
public FlutterEngineGroup(@NonNull Context context) {
this(context, null);
}
/**
* Create a FlutterEngineGroup whose child engines will share resources. Use {@code dartVmArgs} to
* pass flags to the Dart VM during initialization.
*/
public FlutterEngineGroup(@NonNull Context context, @Nullable String[] dartVmArgs) {
FlutterLoader loader = FlutterInjector.instance().flutterLoader();
if (!loader.initialized()) {
loader.startInitialization(context.getApplicationContext());
loader.ensureInitializationComplete(context, dartVmArgs);
}
}
/**
* Creates a {@link io.flutter.embedding.engine.FlutterEngine} in this group and run its {@link
* io.flutter.embedding.engine.dart.DartExecutor} with a default entrypoint of the "main" function
......@@ -67,18 +89,13 @@ public class FlutterEngineGroup {
public FlutterEngine createAndRunEngine(
@NonNull Context context, @Nullable DartEntrypoint dartEntrypoint) {
FlutterEngine engine = null;
// This is done up here because an engine needs to be created first in order to be able to use
// DartEntrypoint.createDefault. The engine creation initializes the FlutterLoader so
// DartEntrypoint known where to find the assets for the AOT or kernel code.
if (activeEngines.size() == 0) {
engine = createEngine(context);
}
if (dartEntrypoint == null) {
dartEntrypoint = DartEntrypoint.createDefault();
}
if (activeEngines.size() == 0) {
engine = createEngine(context);
engine.getDartExecutor().executeDartEntrypoint(dartEntrypoint);
} else {
engine = activeEngines.get(0).spawn(context, dartEntrypoint);
......
......@@ -8,12 +8,17 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import io.flutter.embedding.engine.dart.DartExecutor;
import android.content.res.AssetManager;
import io.flutter.FlutterInjector;
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint;
import io.flutter.embedding.engine.loader.FlutterLoader;
import io.flutter.plugins.GeneratedPluginRegistrant;
......@@ -27,34 +32,41 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
// It's a component test because it tests both FlutterEngineGroup and FlutterEngine.
// It's a component test because it tests the FlutterEngineGroup its components such as the
// FlutterEngine and the DartExecutor.
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class FlutterEngineGroupComponentTest {
@Mock FlutterJNI flutterJNI;
@Mock FlutterJNI mockflutterJNI;
@Mock FlutterLoader mockFlutterLoader;
FlutterEngineGroup engineGroupUnderTest;
FlutterEngine firstEngineUnderTest;
boolean jniAttached;
@Before
public void setUp() {
FlutterInjector.reset();
MockitoAnnotations.initMocks(this);
jniAttached = false;
when(flutterJNI.isAttached()).thenAnswer(invocation -> jniAttached);
doAnswer(invocation -> jniAttached = true).when(flutterJNI).attachToNative(false);
when(mockflutterJNI.isAttached()).thenAnswer(invocation -> jniAttached);
doAnswer(invocation -> jniAttached = true).when(mockflutterJNI).attachToNative(false);
GeneratedPluginRegistrant.clearRegisteredEngines();
when(mockFlutterLoader.findAppBundlePath()).thenReturn("some/path/to/flutter_assets");
FlutterInjector.setInstance(
new FlutterInjector.Builder().setFlutterLoader(mockFlutterLoader).build());
firstEngineUnderTest =
spy(
new FlutterEngine(
RuntimeEnvironment.application,
mock(FlutterLoader.class),
flutterJNI,
mockflutterJNI,
/*dartVmArgs=*/ new String[] {},
/*automaticallyRegisterPlugins=*/ false));
when(firstEngineUnderTest.getDartExecutor()).thenReturn(mock(DartExecutor.class));
engineGroupUnderTest =
new FlutterEngineGroup() {
new FlutterEngineGroup(RuntimeEnvironment.application) {
@Override
FlutterEngine createEngine(Context context) {
return firstEngineUnderTest;
......@@ -127,4 +139,21 @@ public class FlutterEngineGroupComponentTest {
RuntimeEnvironment.application, mock(DartEntrypoint.class));
assertEquals(2, engineGroupUnderTest.activeEngines.size());
}
@Test
public void canCreateAndRunCustomEntrypoints() {
FlutterEngine firstEngine =
engineGroupUnderTest.createAndRunEngine(
RuntimeEnvironment.application,
new DartEntrypoint(
FlutterInjector.instance().flutterLoader().findAppBundlePath(),
"other entrypoint"));
assertEquals(1, engineGroupUnderTest.activeEngines.size());
verify(mockflutterJNI, times(1))
.runBundleAndSnapshotFromLibrary(
eq("some/path/to/flutter_assets"),
eq("other entrypoint"),
isNull(String.class),
any(AssetManager.class));
}
}
......@@ -14,7 +14,7 @@ public class SpawnedEngineActivity extends TestActivity {
@Override
public FlutterEngine provideFlutterEngine(@NonNull Context context) {
FlutterEngineGroup engineGroup = new FlutterEngineGroup();
FlutterEngineGroup engineGroup = new FlutterEngineGroup(context);
engineGroup.createAndRunDefaultEngine(context);
FlutterEngine secondEngine = engineGroup.createAndRunDefaultEngine(context);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册