Flutter Engine
The Flutter Engine
FlutterEngine.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 android.content.pm.PackageManager.NameNotFoundException;
9import android.content.res.AssetManager;
10import androidx.annotation.NonNull;
11import androidx.annotation.Nullable;
12import androidx.annotation.VisibleForTesting;
13import io.flutter.FlutterInjector;
14import io.flutter.Log;
15import io.flutter.embedding.engine.dart.DartExecutor;
16import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint;
17import io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager;
18import io.flutter.embedding.engine.loader.FlutterLoader;
19import io.flutter.embedding.engine.plugins.PluginRegistry;
20import io.flutter.embedding.engine.plugins.activity.ActivityControlSurface;
21import io.flutter.embedding.engine.plugins.broadcastreceiver.BroadcastReceiverControlSurface;
22import io.flutter.embedding.engine.plugins.contentprovider.ContentProviderControlSurface;
23import io.flutter.embedding.engine.plugins.service.ServiceControlSurface;
24import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
25import io.flutter.embedding.engine.renderer.FlutterRenderer;
26import io.flutter.embedding.engine.renderer.RenderSurface;
27import io.flutter.embedding.engine.systemchannels.AccessibilityChannel;
28import io.flutter.embedding.engine.systemchannels.BackGestureChannel;
29import io.flutter.embedding.engine.systemchannels.DeferredComponentChannel;
30import io.flutter.embedding.engine.systemchannels.LifecycleChannel;
31import io.flutter.embedding.engine.systemchannels.LocalizationChannel;
32import io.flutter.embedding.engine.systemchannels.MouseCursorChannel;
33import io.flutter.embedding.engine.systemchannels.NavigationChannel;
34import io.flutter.embedding.engine.systemchannels.PlatformChannel;
35import io.flutter.embedding.engine.systemchannels.ProcessTextChannel;
36import io.flutter.embedding.engine.systemchannels.RestorationChannel;
37import io.flutter.embedding.engine.systemchannels.SettingsChannel;
38import io.flutter.embedding.engine.systemchannels.SpellCheckChannel;
39import io.flutter.embedding.engine.systemchannels.SystemChannel;
40import io.flutter.embedding.engine.systemchannels.TextInputChannel;
41import io.flutter.plugin.localization.LocalizationPlugin;
42import io.flutter.plugin.platform.PlatformViewsController;
43import io.flutter.plugin.text.ProcessTextPlugin;
44import io.flutter.util.ViewUtils;
45import java.util.HashSet;
46import java.util.List;
47import java.util.Set;
48
49/**
50 * A single Flutter execution environment.
51 *
52 * <p>The {@code FlutterEngine} is the container through which Dart code can be run in an Android
53 * application.
54 *
55 * <p>Dart code in a {@code FlutterEngine} can execute in the background, or it can be render to the
56 * screen by using the accompanying {@link FlutterRenderer} and Dart code using the Flutter
57 * framework on the Dart side. Rendering can be started and stopped, thus allowing a {@code
58 * FlutterEngine} to move from UI interaction to data-only processing and then back to UI
59 * interaction.
60 *
61 * <p>Multiple {@code FlutterEngine}s may exist, execute Dart code, and render UIs within a single
62 * Android app. For better memory performance characteristics, construct multiple {@code
63 * FlutterEngine}s via {@link io.flutter.embedding.engine.FlutterEngineGroup} rather than via {@code
64 * FlutterEngine}'s constructor directly.
65 *
66 * <p>To start running Dart and/or Flutter within this {@code FlutterEngine}, get a reference to
67 * this engine's {@link DartExecutor} and then use {@link
68 * DartExecutor#executeDartEntrypoint(DartExecutor.DartEntrypoint)}. The {@link
69 * DartExecutor#executeDartEntrypoint(DartExecutor.DartEntrypoint)} method must not be invoked twice
70 * on the same {@code FlutterEngine}.
71 *
72 * <p>To start rendering Flutter content to the screen, use {@link #getRenderer()} to obtain a
73 * {@link FlutterRenderer} and then attach a {@link RenderSurface}. Consider using a {@link
74 * io.flutter.embedding.android.FlutterView} as a {@link RenderSurface}.
75 *
76 * <p>Instatiating the first {@code FlutterEngine} per process will also load the Flutter engine's
77 * native library and start the Dart VM. Subsequent {@code FlutterEngine}s will run on the same VM
78 * instance but will have their own Dart <a
79 * href="https://api.dartlang.org/stable/dart-isolate/Isolate-class.html">Isolate</a> when the
80 * {@link DartExecutor} is run. Each Isolate is a self-contained Dart environment and cannot
81 * communicate with each other except via Isolate ports.
82 */
83public class FlutterEngine implements ViewUtils.DisplayUpdater {
84 private static final String TAG = "FlutterEngine";
85
86 @NonNull private final FlutterJNI flutterJNI;
87 @NonNull private final FlutterRenderer renderer;
88 @NonNull private final DartExecutor dartExecutor;
89 @NonNull private final FlutterEngineConnectionRegistry pluginRegistry;
90 @NonNull private final LocalizationPlugin localizationPlugin;
91
92 // System channels.
93 @NonNull private final AccessibilityChannel accessibilityChannel;
94 @NonNull private final DeferredComponentChannel deferredComponentChannel;
95 @NonNull private final LifecycleChannel lifecycleChannel;
96 @NonNull private final LocalizationChannel localizationChannel;
97 @NonNull private final MouseCursorChannel mouseCursorChannel;
98 @NonNull private final NavigationChannel navigationChannel;
99 @NonNull private final BackGestureChannel backGestureChannel;
100 @NonNull private final RestorationChannel restorationChannel;
101 @NonNull private final PlatformChannel platformChannel;
102 @NonNull private final ProcessTextChannel processTextChannel;
103 @NonNull private final SettingsChannel settingsChannel;
104 @NonNull private final SpellCheckChannel spellCheckChannel;
105 @NonNull private final SystemChannel systemChannel;
106 @NonNull private final TextInputChannel textInputChannel;
107
108 // Platform Views.
109 @NonNull private final PlatformViewsController platformViewsController;
110
111 // Engine Lifecycle.
112 @NonNull private final Set<EngineLifecycleListener> engineLifecycleListeners = new HashSet<>();
113
114 @NonNull
115 private final EngineLifecycleListener engineLifecycleListener =
117 @SuppressWarnings("unused")
118 public void onPreEngineRestart() {
119 Log.v(TAG, "onPreEngineRestart()");
120 for (EngineLifecycleListener lifecycleListener : engineLifecycleListeners) {
121 lifecycleListener.onPreEngineRestart();
122 }
123
124 platformViewsController.onPreEngineRestart();
125 restorationChannel.clearData();
126 }
127
128 @Override
129 public void onEngineWillDestroy() {
130 // This inner implementation doesn't do anything since FlutterEngine sent this
131 // notification in the first place. It's meant for external listeners.
132 }
133 };
134
135 /**
136 * Constructs a new {@code FlutterEngine}.
137 *
138 * <p>A new {@code FlutterEngine} does not execute any Dart code automatically. See {@link
139 * #getDartExecutor()} and {@link DartExecutor#executeDartEntrypoint(DartExecutor.DartEntrypoint)}
140 * to begin executing Dart code within this {@code FlutterEngine}.
141 *
142 * <p>A new {@code FlutterEngine} will not display any UI until a {@link RenderSurface} is
143 * registered. See {@link #getRenderer()} and {@link
144 * FlutterRenderer#startRenderingToSurface(Surface, boolean)}.
145 *
146 * <p>A new {@code FlutterEngine} automatically attaches all plugins. See {@link #getPlugins()}.
147 *
148 * <p>A new {@code FlutterEngine} does come with all default system channels attached.
149 *
150 * <p>The first {@code FlutterEngine} instance constructed per process will also load the Flutter
151 * native library and start a Dart VM.
152 *
153 * <p>In order to pass Dart VM initialization arguments (see {@link
154 * io.flutter.embedding.engine.FlutterShellArgs}) when creating the VM, manually set the
155 * initialization arguments by calling {@link
156 * io.flutter.embedding.engine.loader.FlutterLoader#startInitialization(Context)} and {@link
157 * io.flutter.embedding.engine.loader.FlutterLoader#ensureInitializationComplete(Context,
158 * String[])} before constructing the engine.
159 */
160 public FlutterEngine(@NonNull Context context) {
161 this(context, null);
162 }
163
164 /**
165 * Same as {@link #FlutterEngine(Context)} with added support for passing Dart VM arguments.
166 *
167 * <p>If the Dart VM has already started, the given arguments will have no effect.
168 */
169 public FlutterEngine(@NonNull Context context, @Nullable String[] dartVmArgs) {
170 this(context, /* flutterLoader */ null, /* flutterJNI */ null, dartVmArgs, true);
171 }
172
173 /**
174 * Same as {@link #FlutterEngine(Context)} with added support for passing Dart VM arguments and
175 * avoiding automatic plugin registration.
176 *
177 * <p>If the Dart VM has already started, the given arguments will have no effect.
178 */
180 @NonNull Context context,
181 @Nullable String[] dartVmArgs,
182 boolean automaticallyRegisterPlugins) {
183 this(
184 context,
185 /* flutterLoader */ null,
186 /* flutterJNI */ null,
187 dartVmArgs,
188 automaticallyRegisterPlugins);
189 }
190
191 /**
192 * Same as {@link #FlutterEngine(Context, String[], boolean)} with added support for configuring
193 * whether the engine will receive restoration data.
194 *
195 * <p>The {@code waitForRestorationData} flag controls whether the engine delays responding to
196 * requests from the framework for restoration data until that data has been provided to the
197 * engine via {@code RestorationChannel.setRestorationData(byte[] data)}. If the flag is false,
198 * the framework may temporarily initialize itself to default values before the restoration data
199 * has been made available to the engine. Setting {@code waitForRestorationData} to true avoids
200 * this extra work by delaying initialization until the data is available.
201 *
202 * <p>When {@code waitForRestorationData} is set, {@code
203 * RestorationChannel.setRestorationData(byte[] data)} must be called at a later point in time. If
204 * it later turns out that no restoration data is available to restore the framework from, that
205 * method must still be called with null as an argument to indicate "no data".
206 *
207 * <p>If the framework never requests the restoration data, this flag has no effect.
208 */
210 @NonNull Context context,
211 @Nullable String[] dartVmArgs,
212 boolean automaticallyRegisterPlugins,
213 boolean waitForRestorationData) {
214 this(
215 context,
216 /* flutterLoader */ null,
217 /* flutterJNI */ null,
219 dartVmArgs,
220 automaticallyRegisterPlugins,
221 waitForRestorationData);
222 }
223
224 /**
225 * Same as {@link #FlutterEngine(Context, FlutterLoader, FlutterJNI, String[], boolean)} but with
226 * no Dart VM flags and automatically registers plugins.
227 *
228 * <p>{@code flutterJNI} should be a new instance that has never been attached to an engine
229 * before.
230 */
232 @NonNull Context context,
233 @Nullable FlutterLoader flutterLoader,
234 @NonNull FlutterJNI flutterJNI) {
235 this(context, flutterLoader, flutterJNI, null, true);
236 }
237
238 /**
239 * Same as {@link #FlutterEngine(Context, FlutterLoader, FlutterJNI)}, plus Dart VM flags in
240 * {@code dartVmArgs}, and control over whether plugins are automatically registered with this
241 * {@code FlutterEngine} in {@code automaticallyRegisterPlugins}. If plugins are automatically
242 * registered, then they are registered during the execution of this constructor.
243 */
245 @NonNull Context context,
246 @Nullable FlutterLoader flutterLoader,
247 @NonNull FlutterJNI flutterJNI,
248 @Nullable String[] dartVmArgs,
249 boolean automaticallyRegisterPlugins) {
250 this(
251 context,
252 flutterLoader,
253 flutterJNI,
255 dartVmArgs,
256 automaticallyRegisterPlugins);
257 }
258
259 /**
260 * Same as {@link #FlutterEngine(Context, FlutterLoader, FlutterJNI, String[], boolean)}, plus the
261 * ability to provide a custom {@code PlatformViewsController}.
262 */
264 @NonNull Context context,
265 @Nullable FlutterLoader flutterLoader,
266 @NonNull FlutterJNI flutterJNI,
267 @NonNull PlatformViewsController platformViewsController,
268 @Nullable String[] dartVmArgs,
269 boolean automaticallyRegisterPlugins) {
270 this(
271 context,
272 flutterLoader,
273 flutterJNI,
274 platformViewsController,
275 dartVmArgs,
276 automaticallyRegisterPlugins,
277 false);
278 }
279
280 /** Fully configurable {@code FlutterEngine} constructor. */
282 @NonNull Context context,
283 @Nullable FlutterLoader flutterLoader,
284 @NonNull FlutterJNI flutterJNI,
285 @NonNull PlatformViewsController platformViewsController,
286 @Nullable String[] dartVmArgs,
287 boolean automaticallyRegisterPlugins,
288 boolean waitForRestorationData) {
289 this(
290 context,
291 flutterLoader,
292 flutterJNI,
293 platformViewsController,
294 dartVmArgs,
295 automaticallyRegisterPlugins,
296 waitForRestorationData,
297 null);
298 }
299
300 @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
302 @NonNull Context context,
303 @Nullable FlutterLoader flutterLoader,
304 @NonNull FlutterJNI flutterJNI,
305 @NonNull PlatformViewsController platformViewsController,
306 @Nullable String[] dartVmArgs,
307 boolean automaticallyRegisterPlugins,
308 boolean waitForRestorationData,
309 @Nullable FlutterEngineGroup group) {
310 AssetManager assetManager;
311 try {
312 assetManager = context.createPackageContext(context.getPackageName(), 0).getAssets();
313 } catch (NameNotFoundException e) {
314 assetManager = context.getAssets();
315 }
316
317 FlutterInjector injector = FlutterInjector.instance();
318
319 if (flutterJNI == null) {
320 flutterJNI = injector.getFlutterJNIFactory().provideFlutterJNI();
321 }
322 this.flutterJNI = flutterJNI;
323
324 this.dartExecutor = new DartExecutor(flutterJNI, assetManager);
325 this.dartExecutor.onAttachedToJNI();
326
327 DeferredComponentManager deferredComponentManager =
328 FlutterInjector.instance().deferredComponentManager();
329
330 accessibilityChannel = new AccessibilityChannel(dartExecutor, flutterJNI);
331 deferredComponentChannel = new DeferredComponentChannel(dartExecutor);
332 lifecycleChannel = new LifecycleChannel(dartExecutor);
333 localizationChannel = new LocalizationChannel(dartExecutor);
334 mouseCursorChannel = new MouseCursorChannel(dartExecutor);
335 navigationChannel = new NavigationChannel(dartExecutor);
336 backGestureChannel = new BackGestureChannel(dartExecutor);
337 platformChannel = new PlatformChannel(dartExecutor);
338 processTextChannel = new ProcessTextChannel(dartExecutor, context.getPackageManager());
339 restorationChannel = new RestorationChannel(dartExecutor, waitForRestorationData);
340 settingsChannel = new SettingsChannel(dartExecutor);
341 spellCheckChannel = new SpellCheckChannel(dartExecutor);
342 systemChannel = new SystemChannel(dartExecutor);
343 textInputChannel = new TextInputChannel(dartExecutor);
344
345 if (deferredComponentManager != null) {
346 deferredComponentManager.setDeferredComponentChannel(deferredComponentChannel);
347 }
348
349 this.localizationPlugin = new LocalizationPlugin(context, localizationChannel);
350
351 if (flutterLoader == null) {
352 flutterLoader = injector.flutterLoader();
353 }
354
355 if (!flutterJNI.isAttached()) {
356 flutterLoader.startInitialization(context.getApplicationContext());
357 flutterLoader.ensureInitializationComplete(context, dartVmArgs);
358 }
359
360 flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
361 flutterJNI.setPlatformViewsController(platformViewsController);
362 flutterJNI.setLocalizationPlugin(localizationPlugin);
363 flutterJNI.setDeferredComponentManager(injector.deferredComponentManager());
364
365 // It should typically be a fresh, unattached JNI. But on a spawned engine, the JNI instance
366 // is already attached to a native shell. In that case, the Java FlutterEngine is created around
367 // an existing shell.
368 if (!flutterJNI.isAttached()) {
369 attachToJni();
370 }
371
372 // TODO(mattcarroll): FlutterRenderer is temporally coupled to attach(). Remove that coupling if
373 // possible.
374 this.renderer = new FlutterRenderer(flutterJNI);
375
376 this.platformViewsController = platformViewsController;
377 this.platformViewsController.onAttachedToJNI();
378
379 this.pluginRegistry =
381 context.getApplicationContext(), this, flutterLoader, group);
382
383 localizationPlugin.sendLocalesToFlutter(context.getResources().getConfiguration());
384
385 // Only automatically register plugins if both constructor parameter and
386 // loaded AndroidManifest config turn this feature on.
387 if (automaticallyRegisterPlugins && flutterLoader.automaticallyRegisterPlugins()) {
389 }
390
392
393 ProcessTextPlugin processTextPlugin = new ProcessTextPlugin(this.getProcessTextChannel());
394 this.pluginRegistry.add(processTextPlugin);
395 }
396
397 private void attachToJni() {
398 Log.v(TAG, "Attaching to JNI.");
399 flutterJNI.attachToNative();
400
401 if (!isAttachedToJni()) {
402 throw new RuntimeException("FlutterEngine failed to attach to its native Object reference.");
403 }
404 }
405
406 @SuppressWarnings("BooleanMethodIsAlwaysInverted")
407 private boolean isAttachedToJni() {
408 return flutterJNI.isAttached();
409 }
410
411 /**
412 * Create a second {@link io.flutter.embedding.engine.FlutterEngine} based on this current one by
413 * sharing as much resources together as possible to minimize startup latency and memory cost.
414 *
415 * @param context is a Context used to create the {@link
416 * io.flutter.embedding.engine.FlutterEngine}. Could be the same Context as the current engine
417 * or a different one. Generally, only an application Context is needed for the {@link
418 * io.flutter.embedding.engine.FlutterEngine} and its dependencies.
419 * @param dartEntrypoint specifies the {@link DartEntrypoint} the new engine should run. It
420 * doesn't need to be the same entrypoint as the current engine but must be built in the same
421 * AOT or snapshot.
422 * @param initialRoute The name of the initial Flutter `Navigator` `Route` to load. If this is
423 * null, it will default to the "/" route.
424 * @param dartEntrypointArgs Arguments passed as a list of string to Dart's entrypoint function.
425 * @return a new {@link io.flutter.embedding.engine.FlutterEngine}.
426 */
427 @NonNull
428 /*package*/ FlutterEngine spawn(
429 @NonNull Context context,
430 @NonNull DartEntrypoint dartEntrypoint,
431 @Nullable String initialRoute,
432 @Nullable List<String> dartEntrypointArgs,
433 @Nullable PlatformViewsController platformViewsController,
434 boolean automaticallyRegisterPlugins,
435 boolean waitForRestorationData) {
436 if (!isAttachedToJni()) {
437 throw new IllegalStateException(
438 "Spawn can only be called on a fully constructed FlutterEngine");
439 }
440
441 FlutterJNI newFlutterJNI =
442 flutterJNI.spawn(
443 dartEntrypoint.dartEntrypointFunctionName,
444 dartEntrypoint.dartEntrypointLibrary,
445 initialRoute,
446 dartEntrypointArgs);
447 return new FlutterEngine(
448 context, // Context.
449 null, // FlutterLoader. A null value passed here causes the constructor to get it from the
450 // FlutterInjector.
451 newFlutterJNI, // FlutterJNI.
452 platformViewsController, // PlatformViewsController.
453 null, // String[]. The Dart VM has already started, this arguments will have no effect.
454 automaticallyRegisterPlugins, // boolean.
455 waitForRestorationData); // boolean
456 }
457
458 /**
459 * Cleans up all components within this {@code FlutterEngine} and destroys the associated Dart
460 * Isolate. All state held by the Dart Isolate, such as the Flutter Elements tree, is lost.
461 *
462 * <p>This {@code FlutterEngine} instance should be discarded after invoking this method.
463 */
464 public void destroy() {
465 Log.v(TAG, "Destroying.");
466 for (EngineLifecycleListener listener : engineLifecycleListeners) {
467 listener.onEngineWillDestroy();
468 }
469 // The order that these things are destroyed is important.
470 pluginRegistry.destroy();
471 platformViewsController.onDetachedFromJNI();
472 dartExecutor.onDetachedFromJNI();
473 flutterJNI.removeEngineLifecycleListener(engineLifecycleListener);
474 flutterJNI.setDeferredComponentManager(null);
475 flutterJNI.detachFromNativeAndReleaseResources();
476 if (FlutterInjector.instance().deferredComponentManager() != null) {
477 FlutterInjector.instance().deferredComponentManager().destroy();
478 deferredComponentChannel.setDeferredComponentManager(null);
479 }
480 }
481
482 /**
483 * Adds a {@code listener} to be notified of Flutter engine lifecycle events, e.g., {@code
484 * onPreEngineStart()}.
485 */
487 engineLifecycleListeners.add(listener);
488 }
489
490 /**
491 * Removes a {@code listener} that was previously added with {@link
492 * #addEngineLifecycleListener(EngineLifecycleListener)}.
493 */
495 engineLifecycleListeners.remove(listener);
496 }
497
498 /**
499 * The Dart execution context associated with this {@code FlutterEngine}.
500 *
501 * <p>The {@link DartExecutor} can be used to start executing Dart code from a given entrypoint.
502 * See {@link DartExecutor#executeDartEntrypoint(DartExecutor.DartEntrypoint)}.
503 *
504 * <p>Use the {@link DartExecutor} to connect any desired message channels and method channels to
505 * facilitate communication between Android and Dart/Flutter.
506 */
507 @NonNull
509 return dartExecutor;
510 }
511
512 /**
513 * The rendering system associated with this {@code FlutterEngine}.
514 *
515 * <p>To render a Flutter UI that is produced by this {@code FlutterEngine}'s Dart code, attach a
516 * {@link RenderSurface} to this {@link FlutterRenderer}.
517 */
518 @NonNull
520 return renderer;
521 }
522
523 /** System channel that sends accessibility requests and events from Flutter to Android. */
524 @NonNull
526 return accessibilityChannel;
527 }
528
529 /** System channel that sends Android lifecycle events to Flutter. */
530 @NonNull
532 return lifecycleChannel;
533 }
534
535 /** System channel that sends locale data from Android to Flutter. */
536 @NonNull
538 return localizationChannel;
539 }
540
541 /** System channel that sends Flutter navigation commands from Android to Flutter. */
542 @NonNull
544 return navigationChannel;
545 }
546
547 /** System channel that sends back gesture commands from Android to Flutter. */
548 @NonNull
550 return backGestureChannel;
551 }
552
553 /**
554 * System channel that sends platform-oriented requests and information to Flutter, e.g., requests
555 * to play sounds, requests for haptics, system chrome settings, etc.
556 */
557 @NonNull
559 return platformChannel;
560 }
561
562 /** System channel that sends text processing requests from Flutter to Android. */
563 @NonNull
565 return processTextChannel;
566 }
567
568 /**
569 * System channel to exchange restoration data between framework and engine.
570 *
571 * <p>The engine can obtain the current restoration data from the framework via this channel to
572 * store it on disk and - when the app is relaunched - provide the stored data back to the
573 * framework to recreate the original state of the app.
574 */
575 @NonNull
577 return restorationChannel;
578 }
579
580 /**
581 * System channel that sends platform/user settings from Android to Flutter, e.g., time format,
582 * scale factor, etc.
583 */
584 @NonNull
586 return settingsChannel;
587 }
588
589 /** System channel that allows manual installation and state querying of deferred components. */
590 @NonNull
592 return deferredComponentChannel;
593 }
594
595 /** System channel that sends memory pressure warnings from Android to Flutter. */
596 @NonNull
598 return systemChannel;
599 }
600
601 /** System channel that sends and receives text input requests and state. */
602 @NonNull
604 return mouseCursorChannel;
605 }
606
607 /** System channel that sends and receives text input requests and state. */
608 @NonNull
610 return textInputChannel;
611 }
612
613 /** System channel that sends and receives spell check requests and results. */
614 @NonNull
616 return spellCheckChannel;
617 }
618
619 /**
620 * Plugin registry, which registers plugins that want to be applied to this {@code FlutterEngine}.
621 */
622 @NonNull
624 return pluginRegistry;
625 }
626
627 /** The LocalizationPlugin this FlutterEngine created. */
628 @NonNull
630 return localizationPlugin;
631 }
632
633 /**
634 * {@code PlatformViewsController}, which controls all platform views running within this {@code
635 * FlutterEngine}.
636 */
637 @NonNull
639 return platformViewsController;
640 }
641
642 @NonNull
644 return pluginRegistry;
645 }
646
647 @NonNull
649 return pluginRegistry;
650 }
651
652 @NonNull
654 return pluginRegistry;
655 }
656
657 @NonNull
659 return pluginRegistry;
660 }
661
662 /** Lifecycle callbacks for Flutter engine lifecycle events. */
663 public interface EngineLifecycleListener {
664 /** Lifecycle callback invoked before a hot restart of the Flutter engine. */
666 /**
667 * Lifecycle callback invoked before the Flutter engine is destroyed.
668 *
669 * <p>For the duration of the call, the Flutter engine is still valid.
670 */
672 }
673
674 @Override
675 public void updateDisplayMetrics(float width, float height, float density) {
676 flutterJNI.updateDisplayMetrics(0 /* display ID */, width, height, density);
677 }
678}
FlutterJNI.Factory getFlutterJNIFactory()
static void v(@NonNull String tag, @NonNull String message)
Definition: Log.java:40
PlatformViewsController getPlatformViewsController()
ActivityControlSurface getActivityControlSurface()
FlutterEngine( @NonNull Context context, @Nullable FlutterLoader flutterLoader, @NonNull FlutterJNI flutterJNI)
FlutterEngine(@NonNull Context context, @Nullable String[] dartVmArgs)
BroadcastReceiverControlSurface getBroadcastReceiverControlSurface()
AccessibilityChannel getAccessibilityChannel()
ContentProviderControlSurface getContentProviderControlSurface()
void updateDisplayMetrics(float width, float height, float density)
FlutterEngine( @NonNull Context context, @Nullable FlutterLoader flutterLoader, @NonNull FlutterJNI flutterJNI, @NonNull PlatformViewsController platformViewsController, @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins, boolean waitForRestorationData)
FlutterEngine spawn( @NonNull Context context, @NonNull DartEntrypoint dartEntrypoint, @Nullable String initialRoute, @Nullable List< String > dartEntrypointArgs, @Nullable PlatformViewsController platformViewsController, boolean automaticallyRegisterPlugins, boolean waitForRestorationData)
ServiceControlSurface getServiceControlSurface()
void addEngineLifecycleListener(@NonNull EngineLifecycleListener listener)
FlutterEngine( @NonNull Context context, @Nullable FlutterLoader flutterLoader, @NonNull FlutterJNI flutterJNI, @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins)
FlutterEngine( @NonNull Context context, @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins, boolean waitForRestorationData)
void removeEngineLifecycleListener(@NonNull EngineLifecycleListener listener)
DeferredComponentChannel getDeferredComponentChannel()
FlutterEngine( @NonNull Context context, @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins)
FlutterEngine( @NonNull Context context, @Nullable FlutterLoader flutterLoader, @NonNull FlutterJNI flutterJNI, @NonNull PlatformViewsController platformViewsController, @Nullable String[] dartVmArgs, boolean automaticallyRegisterPlugins)
FlutterJNI spawn( @Nullable String entrypointFunctionName, @Nullable String pathToEntrypointFunction, @Nullable String initialRoute, @Nullable List< String > entrypointArgs)
void startInitialization(@NonNull Context applicationContext)
static void registerGeneratedPlugins(@NonNull FlutterEngine flutterEngine)
static void calculateMaximumDisplayMetrics( @Nullable Context context, @NonNull DisplayUpdater updater)
Definition: ViewUtils.java:27
abstract void setDeferredComponentChannel(DeferredComponentChannel channel)
#define TAG()
int32_t height
int32_t width