Flutter Engine
The Flutter Engine
FlutterEngineGroup.java
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package io.flutter.embedding.engine;
6
7import android.content.Context;
8import androidx.annotation.NonNull;
9import androidx.annotation.Nullable;
10import androidx.annotation.VisibleForTesting;
11import io.flutter.FlutterInjector;
12import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint;
13import io.flutter.embedding.engine.loader.FlutterLoader;
14import io.flutter.plugin.platform.PlatformViewsController;
15import java.util.ArrayList;
16import java.util.List;
17
18/**
19 * Represents a collection of {@link io.flutter.embedding.engine.FlutterEngine}s who share resources
20 * to allow them to be created faster and with less memory than calling the {@link
21 * io.flutter.embedding.engine.FlutterEngine}'s constructor multiple times.
22 *
23 * <p>When creating or recreating the first {@link io.flutter.embedding.engine.FlutterEngine} in the
24 * FlutterEngineGroup, the behavior is the same as creating a {@link
25 * io.flutter.embedding.engine.FlutterEngine} via its constructor. When subsequent {@link
26 * io.flutter.embedding.engine.FlutterEngine}s are created, resources from an existing living {@link
27 * io.flutter.embedding.engine.FlutterEngine} is re-used.
28 *
29 * <p>The shared resources are kept until the last surviving {@link
30 * io.flutter.embedding.engine.FlutterEngine} is destroyed.
31 *
32 * <p>Deleting a FlutterEngineGroup doesn't invalidate its existing {@link
33 * io.flutter.embedding.engine.FlutterEngine}s, but it eliminates the possibility to create more
34 * {@link io.flutter.embedding.engine.FlutterEngine}s in that group.
35 */
36public class FlutterEngineGroup {
37
38 /* package */ @VisibleForTesting final List<FlutterEngine> activeEngines = new ArrayList<>();
39
40 /**
41 * Create a FlutterEngineGroup whose child engines will share resources.
42 *
43 * <p>Since the FlutterEngineGroup is likely to have a longer lifecycle than any individual
44 * Android component, it's more semantically correct to pass in an application context rather than
45 * the individual Android component's context to minimize the chances of leaks.
46 */
47 public FlutterEngineGroup(@NonNull Context context) {
48 this(context, null);
49 }
50
51 /**
52 * Create a FlutterEngineGroup whose child engines will share resources. Use {@code dartVmArgs} to
53 * pass flags to the Dart VM during initialization.
54 *
55 * <p>Since the FlutterEngineGroup is likely to have a longer lifecycle than any individual
56 * Android component, it's more semantically correct to pass in an application context rather than
57 * the individual Android component's context to minimize the chances of leaks.
58 */
59 public FlutterEngineGroup(@NonNull Context context, @Nullable String[] dartVmArgs) {
60 FlutterLoader loader = FlutterInjector.instance().flutterLoader();
61 if (!loader.initialized()) {
62 loader.startInitialization(context.getApplicationContext());
63 loader.ensureInitializationComplete(context.getApplicationContext(), dartVmArgs);
64 }
65 }
66
67 /**
68 * Creates a {@link io.flutter.embedding.engine.FlutterEngine} in this group and run its {@link
69 * io.flutter.embedding.engine.dart.DartExecutor} with a default entrypoint of the "main" function
70 * in the "lib/main.dart" file.
71 *
72 * <p>If no prior {@link io.flutter.embedding.engine.FlutterEngine} were created in this group,
73 * the initialization cost will be slightly higher than subsequent engines. The very first {@link
74 * io.flutter.embedding.engine.FlutterEngine} created per program, regardless of
75 * FlutterEngineGroup, also incurs the Dart VM creation time.
76 *
77 * <p>Subsequent engine creations will share resources with existing engines. However, if all
78 * existing engines were {@link io.flutter.embedding.engine.FlutterEngine#destroy()}ed, the next
79 * engine created will recreate its dependencies.
80 */
81 public FlutterEngine createAndRunDefaultEngine(@NonNull Context context) {
82 return createAndRunEngine(context, null);
83 }
84
85 /**
86 * Creates a {@link io.flutter.embedding.engine.FlutterEngine} in this group and run its {@link
87 * io.flutter.embedding.engine.dart.DartExecutor} with the specified {@link DartEntrypoint}.
88 *
89 * <p>If no prior {@link io.flutter.embedding.engine.FlutterEngine} were created in this group,
90 * the initialization cost will be slightly higher than subsequent engines. The very first {@link
91 * io.flutter.embedding.engine.FlutterEngine} created per program, regardless of
92 * FlutterEngineGroup, also incurs the Dart VM creation time.
93 *
94 * <p>Subsequent engine creations will share resources with existing engines. However, if all
95 * existing engines were {@link io.flutter.embedding.engine.FlutterEngine#destroy()}ed, the next
96 * engine created will recreate its dependencies.
97 */
99 @NonNull Context context, @Nullable DartEntrypoint dartEntrypoint) {
100 return createAndRunEngine(context, dartEntrypoint, null);
101 }
102
103 /**
104 * Creates a {@link io.flutter.embedding.engine.FlutterEngine} in this group and run its {@link
105 * io.flutter.embedding.engine.dart.DartExecutor} with the specified {@link DartEntrypoint} and
106 * the specified {@code initialRoute}.
107 *
108 * <p>If no prior {@link io.flutter.embedding.engine.FlutterEngine} were created in this group,
109 * the initialization cost will be slightly higher than subsequent engines. The very first {@link
110 * io.flutter.embedding.engine.FlutterEngine} created per program, regardless of
111 * FlutterEngineGroup, also incurs the Dart VM creation time.
112 *
113 * <p>Subsequent engine creations will share resources with existing engines. However, if all
114 * existing engines were {@link io.flutter.embedding.engine.FlutterEngine#destroy()}ed, the next
115 * engine created will recreate its dependencies.
116 */
118 @NonNull Context context,
119 @Nullable DartEntrypoint dartEntrypoint,
120 @Nullable String initialRoute) {
121 return createAndRunEngine(
122 new Options(context).setDartEntrypoint(dartEntrypoint).setInitialRoute(initialRoute));
123 }
124
125 /**
126 * Creates a {@link io.flutter.embedding.engine.FlutterEngine} in this group and run its {@link
127 * io.flutter.embedding.engine.dart.DartExecutor} with the specified {@link DartEntrypoint}, the
128 * specified {@code initialRoute} and the {@code dartEntrypointArgs}.
129 *
130 * <p>If no prior {@link io.flutter.embedding.engine.FlutterEngine} were created in this group,
131 * the initialization cost will be slightly higher than subsequent engines. The very first {@link
132 * io.flutter.embedding.engine.FlutterEngine} created per program, regardless of
133 * FlutterEngineGroup, also incurs the Dart VM creation time.
134 *
135 * <p>Subsequent engine creations will share resources with existing engines. However, if all
136 * existing engines were {@link io.flutter.embedding.engine.FlutterEngine#destroy()}ed, the next
137 * engine created will recreate its dependencies.
138 */
140 FlutterEngine engine = null;
141
142 Context context = options.getContext();
143 DartEntrypoint dartEntrypoint = options.getDartEntrypoint();
144 String initialRoute = options.getInitialRoute();
145 List<String> dartEntrypointArgs = options.getDartEntrypointArgs();
146 PlatformViewsController platformViewsController = options.getPlatformViewsController();
147 platformViewsController =
148 platformViewsController != null ? platformViewsController : new PlatformViewsController();
149 boolean automaticallyRegisterPlugins = options.getAutomaticallyRegisterPlugins();
150 boolean waitForRestorationData = options.getWaitForRestorationData();
151
152 if (dartEntrypoint == null) {
153 dartEntrypoint = DartEntrypoint.createDefault();
154 }
155
156 if (activeEngines.size() == 0) {
157 engine =
159 context,
160 platformViewsController,
161 automaticallyRegisterPlugins,
162 waitForRestorationData);
163 if (initialRoute != null) {
164 engine.getNavigationChannel().setInitialRoute(initialRoute);
165 }
166 engine.getDartExecutor().executeDartEntrypoint(dartEntrypoint, dartEntrypointArgs);
167 } else {
168 engine =
170 .get(0)
171 .spawn(
172 context,
173 dartEntrypoint,
174 initialRoute,
175 dartEntrypointArgs,
176 platformViewsController,
177 automaticallyRegisterPlugins,
178 waitForRestorationData);
179 }
180
182
183 final FlutterEngine engineToCleanUpOnDestroy = engine;
184 engine.addEngineLifecycleListener(
186
187 @Override
188 public void onPreEngineRestart() {
189 // No-op. Not interested.
190 }
191
192 @Override
193 public void onEngineWillDestroy() {
194 activeEngines.remove(engineToCleanUpOnDestroy);
195 }
196 });
197 return engine;
198 }
199
200 @VisibleForTesting
202 Context context,
203 @NonNull PlatformViewsController platformViewsController,
204 boolean automaticallyRegisterPlugins,
205 boolean waitForRestorationData) {
206 return new FlutterEngine(
207 context, // Context.
208 null, // FlutterLoader.
209 null, // FlutterJNI.
210 platformViewsController, // PlatformViewsController.
211 null, // String[]. The Dart VM has already started, this arguments will have no effect.
212 automaticallyRegisterPlugins, // boolean.
213 waitForRestorationData, // boolean.
214 this);
215 }
216
217 /** Options that control how a FlutterEngine should be created. */
218 public static class Options {
219 @NonNull private Context context;
220 @Nullable private DartEntrypoint dartEntrypoint;
221 @Nullable private String initialRoute;
222 @Nullable private List<String> dartEntrypointArgs;
223 @NonNull private PlatformViewsController platformViewsController;
224 private boolean automaticallyRegisterPlugins = true;
225 private boolean waitForRestorationData = false;
226
227 public Options(@NonNull Context context) {
228 this.context = context;
229 }
230
231 public Context getContext() {
232 return context;
233 }
234
235 /**
236 * dartEntrypoint specifies the {@link DartEntrypoint} the new engine should run. It doesn't
237 * need to be the same entrypoint as the current engine but must be built in the same AOT or
238 * snapshot.
239 */
241 return dartEntrypoint;
242 }
243
244 /**
245 * The name of the initial Flutter `Navigator` `Route` to load. If this is null, it will default
246 * to the "/" route.
247 */
248 public String getInitialRoute() {
249 return initialRoute;
250 }
251
252 /** Arguments passed as a list of string to Dart's entrypoint function. */
254 return dartEntrypointArgs;
255 }
256
257 /** Manages platform views. */
259 return platformViewsController;
260 }
261
262 /**
263 * If plugins are automatically registered, then they are registered during the {@link
264 * io.flutter.embedding.engine.FlutterEngine}'s constructor.
265 */
267 return automaticallyRegisterPlugins;
268 }
269
270 /**
271 * The waitForRestorationData flag controls whether the engine delays responding to requests
272 * from the framework for restoration data until that data has been provided to the engine via
273 * {@code RestorationChannel.setRestorationData(byte[] data)}.
274 */
275 public boolean getWaitForRestorationData() {
276 return waitForRestorationData;
277 }
278
279 /**
280 * Setter for `dartEntrypoint` property.
281 *
282 * @param dartEntrypoint specifies the {@link DartEntrypoint} the new engine should run. It
283 * doesn't need to be the same entrypoint as the current engine but must be built in the
284 * same AOT or snapshot.
285 */
286 public Options setDartEntrypoint(DartEntrypoint dartEntrypoint) {
287 this.dartEntrypoint = dartEntrypoint;
288 return this;
289 }
290
291 /**
292 * Setter for `initialRoute` property.
293 *
294 * @param initialRoute The name of the initial Flutter `Navigator` `Route` to load. If this is
295 * null, it will default to the "/" route.
296 */
297 public Options setInitialRoute(String initialRoute) {
298 this.initialRoute = initialRoute;
299 return this;
300 }
301
302 /**
303 * Setter for `dartEntrypointArgs` property.
304 *
305 * @param dartEntrypointArgs Arguments passed as a list of string to Dart's entrypoint function.
306 */
307 public Options setDartEntrypointArgs(List<String> dartEntrypointArgs) {
308 this.dartEntrypointArgs = dartEntrypointArgs;
309 return this;
310 }
311
312 /**
313 * Setter for `platformViewsController` property.
314 *
315 * @param platformViewsController Manages platform views.
316 */
318 @NonNull PlatformViewsController platformViewsController) {
319 this.platformViewsController = platformViewsController;
320 return this;
321 }
322
323 /**
324 * Setter for `automaticallyRegisterPlugins` property.
325 *
326 * @param automaticallyRegisterPlugins If plugins are automatically registered, then they are
327 * registered during the execution of {@link io.flutter.embedding.engine.FlutterEngine}'s
328 * constructor.
329 */
330 public Options setAutomaticallyRegisterPlugins(boolean automaticallyRegisterPlugins) {
331 this.automaticallyRegisterPlugins = automaticallyRegisterPlugins;
332 return this;
333 }
334
335 /**
336 * Setter for `waitForRestorationData` property.
337 *
338 * @param waitForRestorationData The waitForRestorationData flag controls whether the engine
339 * delays responding to requests from the framework for restoration data until that data has
340 * been provided to the engine via {@code RestorationChannel.setRestorationData(byte[]
341 * data)}.
342 */
343 public Options setWaitForRestorationData(boolean waitForRestorationData) {
344 this.waitForRestorationData = waitForRestorationData;
345 return this;
346 }
347 }
348}
const char * options
Options setDartEntrypointArgs(List< String > dartEntrypointArgs)
Options setPlatformViewsController( @NonNull PlatformViewsController platformViewsController)
Options setWaitForRestorationData(boolean waitForRestorationData)
Options setDartEntrypoint(DartEntrypoint dartEntrypoint)
Options setAutomaticallyRegisterPlugins(boolean automaticallyRegisterPlugins)
FlutterEngine createAndRunDefaultEngine(@NonNull Context context)
FlutterEngineGroup(@NonNull Context context, @Nullable String[] dartVmArgs)
FlutterEngine createAndRunEngine( @NonNull Context context, @Nullable DartEntrypoint dartEntrypoint, @Nullable String initialRoute)
FlutterEngine createAndRunEngine(@NonNull Options options)
FlutterEngine createAndRunEngine( @NonNull Context context, @Nullable DartEntrypoint dartEntrypoint)
FlutterEngine createEngine(Context context, @NonNull PlatformViewsController platformViewsController, boolean automaticallyRegisterPlugins, boolean waitForRestorationData)
void ensureInitializationComplete( @NonNull Context applicationContext, @Nullable String[] args)
void startInitialization(@NonNull Context applicationContext)
FlutterEngine engine
Definition: main.cc:68