io.flutter.embedding.engine

## Class FlutterJNI

- java.lang.Object
- - io.flutter.embedding.engine.FlutterJNI

-     public class FlutterJNI
      extends Object

  Interface between Flutter embedding's Java code and Flutter engine's C/C++ code.

  Flutter's engine is built with C/C++. The Android Flutter embedding is responsible for coordinating Android OS events and app user interactions with the C/C++ engine. Such coordination requires messaging from an Android app in Java code to the C/C++ engine code. This communication requires a JNI (Java Native Interface) API to cross the Java/native boundary.

  The entirety of Flutter's JNI API is codified in `FlutterJNI`. There are multiple reasons that all such calls are centralized in one class. First, JNI calls are inherently static and contain no Java implementation, therefore there is little reason to associate calls with different classes. Second, every JNI call must be registered in C/C++ code and this registration becomes more complicated with every additional Java class that contains JNI calls. Third, most Android developers are not familiar with native development or JNI intricacies, therefore it is in the interest of future maintenance to reduce the API surface that includes JNI declarations. Thus, all Flutter JNI calls are centralized in `FlutterJNI`.

  Despite the fact that individual JNI calls are inherently static, there is state that exists within `FlutterJNI`. Most calls within `FlutterJNI` correspond to a specific "platform view", of which there may be many. Therefore, each `FlutterJNI` instance holds onto a "native platform view ID" after `attachToNative(boolean)`, which is shared with the native C/C++ engine code. That ID is passed to every platform-view-specific native method. ID management is handled within `FlutterJNI` so that developers don't have to hold onto that ID.

  To connect part of an Android app to Flutter's C/C++ engine, instantiate a `FlutterJNI` and then attach it to the native side:

       // Instantiate FlutterJNI and attach to the native side.
       FlutterJNI flutterJNI = new FlutterJNI();
       flutterJNI.attachToNative();

       // Use FlutterJNI as desired. flutterJNI.dispatchPointerDataPacket(...);

       // Destroy the connection to the native side and cleanup.
       flutterJNI.detachFromNativeAndReleaseResources();

  To provide a visual, interactive surface for Flutter rendering and touch events, register a `RenderSurface` with `#setRenderSurface(RenderSurface)`

  To receive callbacks for certain events that occur on the native side, register listeners:

  1. `#addEngineLifecycleListener(EngineLifecycleListener)`
  2. `addIsDisplayingFlutterUiListener(FlutterUiDisplayListener)`
  To facilitate platform messages between Java and Dart running in Flutter, register a handler:

  `setPlatformMessageHandler(PlatformMessageHandler)`

  To invoke a native method that is not associated with a platform view, invoke it statically:

  `bool enabled = FlutterJNI.getIsSoftwareRenderingEnabled();`

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `FlutterJNI.AccessibilityDelegate` Delegate responsible for creating and updating Android-side caches of Flutter's semantics tree and custom accessibility actions.
    `static interface` | `FlutterJNI.AsyncWaitForVsyncDelegate`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `FlutterJNI()`

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addEngineLifecycleListener(FlutterEngine.EngineLifecycleListener engineLifecycleListener)` Adds the given `engineLifecycleListener` to be notified of Flutter engine lifecycle events, e.g., `FlutterEngine.EngineLifecycleListener.onPreEngineRestart()`.
    `void` | `addIsDisplayingFlutterUiListener(FlutterUiDisplayListener listener)` Adds a `FlutterUiDisplayListener`, which receives a callback when Flutter's engine notifies `FlutterJNI` that Flutter is painting pixels to the `Surface` that was provided to Flutter.
    `void` | `attachToNative(boolean isBackgroundView)` Attaches this `FlutterJNI` instance to Flutter's native engine, which allows for communication between Android code and Flutter's platform agnostic engine.
    `FlutterOverlaySurface` | `createOverlaySurface()`
    `void` | `deferredComponentInstallFailure(int loadingUnitId, String error, boolean isTransient)` Indicates that a failure was encountered during the Android portion of downloading a dynamic feature module and loading a dart deferred library, which is typically done by DeferredComponentManager.
    `void` | `destroyOverlaySurfaces()`
    `void` | `detachFromNativeAndReleaseResources()` Detaches this `FlutterJNI` instance from Flutter's native engine, which precludes any further communication between Android code and Flutter's platform agnostic engine.
    `void` | `dispatchEmptyPlatformMessage(String channel, int responseId)` Sends an empty reply (identified by `responseId`) from Android to Flutter over the given `channel`.
    `void` | `dispatchPlatformMessage(String channel, ByteBuffer message, int position, int responseId)` Sends a reply `message` from Android to Flutter over the given `channel`.
    `void` | `dispatchPointerDataPacket(ByteBuffer buffer, int position)` Sends a packet of pointer data to Flutter's engine.
    `void` | `dispatchSemanticsAction(int id, AccessibilityBridge.Action action)` Sends a semantics action to Flutter's engine, without any additional arguments.
    `void` | `dispatchSemanticsAction(int id, AccessibilityBridge.Action action, Object args)` Sends a semantics action to Flutter's engine, with additional arguments.
    `void` | `dispatchSemanticsAction(int id, int action, ByteBuffer args, int argsPosition)` Sends a semantics action to Flutter's engine, given arguments that are already encoded for the engine.
    `Bitmap` | `getBitmap()`
    `boolean` | `getIsSoftwareRenderingEnabled()`
    `static String` | `getObservatoryUri()`
    `void` | `handlePlatformMessage(String channel, byte[] message, int replyId)`
    `void` | `init(Context context, String[] args, String bundlePath, String appStoragePath, String engineCachesPath, long initTimeMillis)` Perform one time initialization of the Dart VM and Flutter engine.
    `void` | `invokePlatformMessageEmptyResponseCallback(int responseId)`
    `void` | `invokePlatformMessageResponseCallback(int responseId, ByteBuffer message, int position)`
    `boolean` | `isAttached()` Returns true if this instance of `FlutterJNI` is connected to Flutter's native engine via a Java Native Interface (JNI).
    `void` | `loadDartDeferredLibrary(int loadingUnitId, String[] searchPaths)` Searches each of the provided paths for a valid Dart shared library .so file and resolves symbols to load into the dart VM.
    `void` | `loadLibrary()` Loads the libflutter.so C++ library.
    `void` | `markTextureFrameAvailable(long textureId)` Call this method to inform Flutter that a texture previously registered with `#registerTexture(long, SurfaceTexture)` has a new frame available.
    `boolean` | `nativeFlutterTextUtilsIsEmoji(int codePoint)`
    `boolean` | `nativeFlutterTextUtilsIsEmojiModifier(int codePoint)`
    `boolean` | `nativeFlutterTextUtilsIsEmojiModifierBase(int codePoint)`
    `boolean` | `nativeFlutterTextUtilsIsRegionalIndicator(int codePoint)`
    `boolean` | `nativeFlutterTextUtilsIsVariationSelector(int codePoint)`
    `static void` | `nativeInit(Context context, String[] args, String bundlePath, String appStoragePath, String engineCachesPath, long initTimeMillis)` Deprecated. Use `init(Context, String[], String, String, String, long)` instead.
    `static FlutterCallbackInformation` | `nativeLookupCallbackInformation(long handle)`
    `static void` | `nativeOnVsync(long frameTimeNanos, long frameTargetTimeNanos, long cookie)`
    `static void` | `nativePrefetchDefaultFontManager()` Deprecated. Use `prefetchDefaultFontManager()` instead.
    `void` | `notifyLowMemoryWarning()` Notifies the Dart VM of a low memory event, or that the application is in a state such that now is an appropriate time to free resources, such as going to the background.
    `void` | `onBeginFrame()`
    `void` | `onDisplayOverlaySurface(int id, int x, int y, int width, int height)`
    `void` | `onDisplayPlatformView(int viewId, int x, int y, int width, int height, int viewWidth, int viewHeight, FlutterMutatorsStack mutatorsStack)`
    `void` | `onEndFrame()`
    `void` | `onFirstFrame()`
    `void` | `onSurfaceChanged(int width, int height)` Call this method when the `Surface` changes that was previously registered with `onSurfaceCreated(Surface)`.
    `void` | `onSurfaceCreated(Surface surface)` Call this method when a `Surface` has been created onto which you would like Flutter to paint.
    `void` | `onSurfaceDestroyed()` Call this method when the `Surface` is destroyed that was previously registered with `onSurfaceCreated(Surface)`.
    `void` | `onSurfaceWindowChanged(Surface surface)` In hybrid composition, call this method when the `Surface` has changed.
    `long` | `performNativeAttach(FlutterJNI flutterJNI, boolean isBackgroundView)`
    `void` | `prefetchDefaultFontManager()` Prefetch the default font manager provided by SkFontMgr::RefDefault() which is a process-wide singleton owned by Skia.
    `void` | `registerTexture(long textureId, SurfaceTextureWrapper textureWrapper)` Gives control of a `SurfaceTexture` to Flutter so that Flutter can display that texture within Flutter's UI.
    `void` | `removeEngineLifecycleListener(FlutterEngine.EngineLifecycleListener engineLifecycleListener)` Removes the given `engineLifecycleListener`, which was previously added using `addIsDisplayingFlutterUiListener(FlutterUiDisplayListener)`.
    `void` | `removeIsDisplayingFlutterUiListener(FlutterUiDisplayListener listener)` Removes a `FlutterUiDisplayListener` that was added with `addIsDisplayingFlutterUiListener(FlutterUiDisplayListener)`.
    `void` | `requestDartDeferredLibrary(int loadingUnitId)` Called by dart to request that a Dart deferred library corresponding to loadingUnitId be downloaded (if necessary) and loaded into the dart vm.
    `void` | `runBundleAndSnapshotFromLibrary(String bundlePath, String entrypointFunctionName, String pathToEntrypointFunction, AssetManager assetManager)` Executes a Dart entrypoint.
    `void` | `setAccessibilityDelegate(FlutterJNI.AccessibilityDelegate accessibilityDelegate)` Sets the `FlutterJNI.AccessibilityDelegate` for the attached Flutter context.
    `void` | `setAccessibilityFeatures(int flags)`
    `static void` | `setAsyncWaitForVsyncDelegate(FlutterJNI.AsyncWaitForVsyncDelegate delegate)`
    `void` | `setDeferredComponentManager(io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager deferredComponentManager)` Sets the deferred component manager that is used to download and install split features.
    `void` | `setLocalizationPlugin(io.flutter.plugin.localization.LocalizationPlugin localizationPlugin)` Sets the localization plugin that is used in various localization methods.
    `void` | `setPlatformMessageHandler(PlatformMessageHandler platformMessageHandler)` Sets the handler for all platform messages that come from the attached platform view to Java.
    `void` | `setPlatformViewsController(PlatformViewsController platformViewsController)`
    `static void` | `setRefreshRateFPS(float refreshRateFPS)`
    `void` | `setSemanticsEnabled(boolean enabled)` Instructs Flutter to enable/disable its semantics tree, which is used by Flutter to support accessibility and related behaviors.
    `void` | `setViewportMetrics(float devicePixelRatio, int physicalWidth, int physicalHeight, int physicalPaddingTop, int physicalPaddingRight, int physicalPaddingBottom, int physicalPaddingLeft, int physicalViewInsetTop, int physicalViewInsetRight, int physicalViewInsetBottom, int physicalViewInsetLeft, int systemGestureInsetTop, int systemGestureInsetRight, int systemGestureInsetBottom, int systemGestureInsetLeft)` Call this method to notify Flutter of the current device viewport metrics that are applies to the Flutter UI that is being rendered.
    `FlutterJNI` | `spawn(String entrypointFunctionName, String pathToEntrypointFunction)` Spawns a new FlutterJNI instance from the current instance.
    `void` | `unregisterTexture(long textureId)` Unregisters a texture that was registered with `#registerTexture(long, SurfaceTexture)`.
    `void` | `updateJavaAssetManager(AssetManager assetManager, String assetBundlePath)` Adds the specified AssetManager as an APKAssetResolver in the Flutter Engine's AssetManager.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### FlutterJNI

          public FlutterJNI()

  - ### Method Detail

    - #### loadLibrary

          public void loadLibrary()

      Loads the libflutter.so C++ library.

      This must be called before any other native methods, and can be overridden by tests to avoid loading native libraries.

      This method should only be called once across all FlutterJNI instances.

    - #### prefetchDefaultFontManager

          public void prefetchDefaultFontManager()

      Prefetch the default font manager provided by SkFontMgr::RefDefault() which is a process-wide singleton owned by Skia. Note that, the first call to SkFontMgr::RefDefault() will take noticeable time, but later calls will return a reference to the preexisting font manager.

      This method should only be called once across all FlutterJNI instances.

    - #### init

          public void init(@NonNull
                           Context context,
                           @NonNull
                           String[] args,
                           @Nullable
                           String bundlePath,
                           @NonNull
                           String appStoragePath,
                           @NonNull
                           String engineCachesPath,
                           long initTimeMillis)

      Perform one time initialization of the Dart VM and Flutter engine.

      This method must be called only once. Calling more than once will cause an exception.

      Parameters:
        `context` - The application context.
        `args` - Arguments to the Dart VM/Flutter engine.
        `bundlePath` - For JIT runtimes, the path to the Dart kernel file for the application.
        `appStoragePath` - The path to the application data directory.
        `engineCachesPath` - The path to the application cache directory.
        `initTimeMillis` - The time, in milliseconds, taken for initialization.

    - #### nativeInit

          @Deprecated
          public static void nativeInit(@NonNull
                                                    Context context,
                                                    @NonNull
                                                    String[] args,
                                                    @Nullable
                                                    String bundlePath,
                                                    @NonNull
                                                    String appStoragePath,
                                                    @NonNull
                                                    String engineCachesPath,
                                                    long initTimeMillis)

      Deprecated. Use `init(Context, String[], String, String, String, long)` instead.

    - #### nativePrefetchDefaultFontManager

          @Deprecated
          public static void nativePrefetchDefaultFontManager()

      Deprecated. Use `prefetchDefaultFontManager()` instead.

    - #### getIsSoftwareRenderingEnabled

          @UiThread
          public boolean getIsSoftwareRenderingEnabled()

    - #### getObservatoryUri

          @Nullable
          public static String getObservatoryUri()

    - #### setRefreshRateFPS

          public static void setRefreshRateFPS(float refreshRateFPS)

    - #### setAsyncWaitForVsyncDelegate

          public static void setAsyncWaitForVsyncDelegate(@Nullable
                                                          FlutterJNI.AsyncWaitForVsyncDelegate delegate)

    - #### nativeOnVsync

          public static void nativeOnVsync(long frameTimeNanos,
                                           long frameTargetTimeNanos,
                                           long cookie)

    - #### nativeLookupCallbackInformation

          @NonNull
          public static FlutterCallbackInformation nativeLookupCallbackInformation(long handle)

    - #### nativeFlutterTextUtilsIsEmoji

          public boolean nativeFlutterTextUtilsIsEmoji(int codePoint)

    - #### nativeFlutterTextUtilsIsEmojiModifier

          public boolean nativeFlutterTextUtilsIsEmojiModifier(int codePoint)

    - #### nativeFlutterTextUtilsIsEmojiModifierBase

          public boolean nativeFlutterTextUtilsIsEmojiModifierBase(int codePoint)

    - #### nativeFlutterTextUtilsIsVariationSelector

          public boolean nativeFlutterTextUtilsIsVariationSelector(int codePoint)

    - #### nativeFlutterTextUtilsIsRegionalIndicator

          public boolean nativeFlutterTextUtilsIsRegionalIndicator(int codePoint)

    - #### isAttached

          public boolean isAttached()

      Returns true if this instance of `FlutterJNI` is connected to Flutter's native engine via a Java Native Interface (JNI).

    - #### attachToNative

          @UiThread
          public void attachToNative(boolean isBackgroundView)

      Attaches this `FlutterJNI` instance to Flutter's native engine, which allows for communication between Android code and Flutter's platform agnostic engine.

      This method must not be invoked if `FlutterJNI` is already attached to native.

    - #### performNativeAttach

          public long performNativeAttach(@NonNull
                                          FlutterJNI flutterJNI,
                                          boolean isBackgroundView)

    - #### spawn

          @UiThread
           @NonNull
          public FlutterJNI spawn(@Nullable
                                                      String entrypointFunctionName,
                                                      @Nullable
                                                      String pathToEntrypointFunction)

      Spawns a new FlutterJNI instance from the current instance.

      This creates another native shell from the current shell. This causes the 2 shells to re-use some of the shared resources, reducing the total memory consumption versus creating a new FlutterJNI by calling its standard constructor.

      This can only be called once the current FlutterJNI instance is attached by calling `attachToNative(boolean)`.

      Static methods that should be only called once such as `init(Context, String[], String, String, String, long)` or `setRefreshRateFPS(float)` shouldn't be called again on the spawned FlutterJNI instance.

    - #### detachFromNativeAndReleaseResources

          @UiThread
          public void detachFromNativeAndReleaseResources()

      Detaches this `FlutterJNI` instance from Flutter's native engine, which precludes any further communication between Android code and Flutter's platform agnostic engine.

      This method must not be invoked if `FlutterJNI` is not already attached to native.

      Invoking this method will result in the release of all native-side resources that were set up during `attachToNative(boolean)` or `spawn(String, String)`, or accumulated thereafter.

      It is permissible to re-attach this instance to native after detaching it from native.

    - #### addIsDisplayingFlutterUiListener

          @UiThread
          public void addIsDisplayingFlutterUiListener(@NonNull
                                                                 FlutterUiDisplayListener listener)

      Adds a `FlutterUiDisplayListener`, which receives a callback when Flutter's engine notifies `FlutterJNI` that Flutter is painting pixels to the `Surface` that was provided to Flutter.

    - #### removeIsDisplayingFlutterUiListener

          @UiThread
          public void removeIsDisplayingFlutterUiListener(@NonNull
                                                                    FlutterUiDisplayListener listener)

      Removes a `FlutterUiDisplayListener` that was added with `addIsDisplayingFlutterUiListener(FlutterUiDisplayListener)`.

    - #### onFirstFrame

          @UiThread
          public void onFirstFrame()

    - #### onSurfaceCreated

          @UiThread
          public void onSurfaceCreated(@NonNull
                                                 Surface surface)

      Call this method when a `Surface` has been created onto which you would like Flutter to paint.

      See `SurfaceHolder.Callback.surfaceCreated(SurfaceHolder)` for an example of where this call might originate.

    - #### onSurfaceWindowChanged

          @UiThread
          public void onSurfaceWindowChanged(@NonNull
                                                       Surface surface)

      In hybrid composition, call this method when the `Surface` has changed.

      In hybrid composition, the root surfaces changes from `SurfaceHolder.getSurface()` to `ImageReader.getSurface()` when a platform view is in the current frame.

    - #### onSurfaceChanged

          @UiThread
          public void onSurfaceChanged(int width,
                                                 int height)

      Call this method when the `Surface` changes that was previously registered with `onSurfaceCreated(Surface)`.

      See `SurfaceHolder.Callback.surfaceChanged(SurfaceHolder, int, int, int)` for an example of where this call might originate.

    - #### onSurfaceDestroyed

          @UiThread
          public void onSurfaceDestroyed()

      Call this method when the `Surface` is destroyed that was previously registered with `onSurfaceCreated(Surface)`.

      See `SurfaceHolder.Callback.surfaceDestroyed(SurfaceHolder)` for an example of where this call might originate.

    - #### setViewportMetrics

          @UiThread
          public void setViewportMetrics(float devicePixelRatio,
                                                   int physicalWidth,
                                                   int physicalHeight,
                                                   int physicalPaddingTop,
                                                   int physicalPaddingRight,
                                                   int physicalPaddingBottom,
                                                   int physicalPaddingLeft,
                                                   int physicalViewInsetTop,
                                                   int physicalViewInsetRight,
                                                   int physicalViewInsetBottom,
                                                   int physicalViewInsetLeft,
                                                   int systemGestureInsetTop,
                                                   int systemGestureInsetRight,
                                                   int systemGestureInsetBottom,
                                                   int systemGestureInsetLeft)

      Call this method to notify Flutter of the current device viewport metrics that are applies to the Flutter UI that is being rendered.

      This method should be invoked with initial values upon attaching to native. Then, it should be invoked any time those metrics change while `FlutterJNI` is attached to native.

    - #### dispatchPointerDataPacket

          @UiThread
          public void dispatchPointerDataPacket(@NonNull
                                                          ByteBuffer buffer,
                                                          int position)

      Sends a packet of pointer data to Flutter's engine.

    - #### setPlatformViewsController

          @UiThread
          public void setPlatformViewsController(@NonNull
                                                           PlatformViewsController platformViewsController)

    - #### setAccessibilityDelegate

          @UiThread
          public void setAccessibilityDelegate(@Nullable
                                                         FlutterJNI.AccessibilityDelegate accessibilityDelegate)

      Sets the `FlutterJNI.AccessibilityDelegate` for the attached Flutter context.

      The `FlutterJNI.AccessibilityDelegate` is responsible for maintaining an Android-side cache of Flutter's semantics tree and custom accessibility actions. This cache should be hooked up to Android's accessibility system.

      See `AccessibilityBridge` for an example of an `FlutterJNI.AccessibilityDelegate` and the surrounding responsibilities.

    - #### dispatchSemanticsAction

          public void dispatchSemanticsAction(int id,
                                              @NonNull
                                              AccessibilityBridge.Action action)

      Sends a semantics action to Flutter's engine, without any additional arguments.

    - #### dispatchSemanticsAction

          public void dispatchSemanticsAction(int id,
                                              @NonNull
                                              AccessibilityBridge.Action action,
                                              @Nullable
                                              Object args)

      Sends a semantics action to Flutter's engine, with additional arguments.

    - #### dispatchSemanticsAction

          @UiThread
          public void dispatchSemanticsAction(int id,
                                                        int action,
                                                        @Nullable
                                                        ByteBuffer args,
                                                        int argsPosition)

      Sends a semantics action to Flutter's engine, given arguments that are already encoded for the engine.

      To send a semantics action that has not already been encoded, see `dispatchSemanticsAction(int, AccessibilityBridge.Action)` and `dispatchSemanticsAction(int, AccessibilityBridge.Action, Object)`.

    - #### setSemanticsEnabled

          @UiThread
          public void setSemanticsEnabled(boolean enabled)

      Instructs Flutter to enable/disable its semantics tree, which is used by Flutter to support accessibility and related behaviors.

    - #### setAccessibilityFeatures

          @UiThread
          public void setAccessibilityFeatures(int flags)

    - #### registerTexture

          @UiThread
          public void registerTexture(long textureId,
                                                @NonNull
                                                SurfaceTextureWrapper textureWrapper)

      Gives control of a `SurfaceTexture` to Flutter so that Flutter can display that texture within Flutter's UI.

    - #### markTextureFrameAvailable

          @UiThread
          public void markTextureFrameAvailable(long textureId)

      Call this method to inform Flutter that a texture previously registered with `#registerTexture(long, SurfaceTexture)` has a new frame available.

      Invoking this method instructs Flutter to update its presentation of the given texture so that the new frame is displayed.

    - #### unregisterTexture

          @UiThread
          public void unregisterTexture(long textureId)

      Unregisters a texture that was registered with `#registerTexture(long, SurfaceTexture)`.

    - #### runBundleAndSnapshotFromLibrary

          @UiThread
          public void runBundleAndSnapshotFromLibrary(@NonNull
                                                                String bundlePath,
                                                                @Nullable
                                                                String entrypointFunctionName,
                                                                @Nullable
                                                                String pathToEntrypointFunction,
                                                                @NonNull
                                                                AssetManager assetManager)

      Executes a Dart entrypoint.

      This can only be done once per JNI attachment because a Dart isolate can only be entered once.

    - #### setPlatformMessageHandler

          @UiThread
          public void setPlatformMessageHandler(@Nullable
                                                          PlatformMessageHandler platformMessageHandler)

      Sets the handler for all platform messages that come from the attached platform view to Java.

      Communication between a specific Flutter context (Dart) and the host platform (Java) is accomplished by passing messages. Messages can be sent from Java to Dart with the corresponding `FlutterJNI` methods:

      - `dispatchPlatformMessage(String, ByteBuffer, int, int)`
      - `dispatchEmptyPlatformMessage(String, int)`

      `FlutterJNI` is also the recipient of all platform messages sent from its attached Flutter context. `FlutterJNI` does not know what to do with these messages, so a handler is exposed to allow these messages to be processed in whatever manner is desired:

      `setPlatformMessageHandler(PlatformMessageHandler)`

      If a message is received but no `PlatformMessageHandler` is registered, that message will be dropped (ignored). Therefore, when using `FlutterJNI` to integrate a Flutter context in an app, a `PlatformMessageHandler` must be registered for 2-way Java/Dart communication to operate correctly. Moreover, the handler must be implemented such that fundamental platform messages are handled as expected. See `FlutterNativeView` for an example implementation.

    - #### handlePlatformMessage

          public void handlePlatformMessage(@NonNull
                                            String channel,
                                            byte[] message,
                                            int replyId)

    - #### dispatchEmptyPlatformMessage

          @UiThread
          public void dispatchEmptyPlatformMessage(@NonNull
                                                             String channel,
                                                             int responseId)

      Sends an empty reply (identified by `responseId`) from Android to Flutter over the given `channel`.

    - #### dispatchPlatformMessage

          @UiThread
          public void dispatchPlatformMessage(@NonNull
                                                        String channel,
                                                        @Nullable
                                                        ByteBuffer message,
                                                        int position,
                                                        int responseId)

      Sends a reply `message` from Android to Flutter over the given `channel`.

    - #### invokePlatformMessageEmptyResponseCallback

          @UiThread
          public void invokePlatformMessageEmptyResponseCallback(int responseId)

    - #### invokePlatformMessageResponseCallback

          @UiThread
          public void invokePlatformMessageResponseCallback(int responseId,
                                                                      @Nullable
                                                                      ByteBuffer message,
                                                                      int position)

    - #### addEngineLifecycleListener

          @UiThread
          public void addEngineLifecycleListener(@NonNull
                                                           FlutterEngine.EngineLifecycleListener engineLifecycleListener)

      Adds the given `engineLifecycleListener` to be notified of Flutter engine lifecycle events, e.g., `FlutterEngine.EngineLifecycleListener.onPreEngineRestart()`.

    - #### removeEngineLifecycleListener

          @UiThread
          public void removeEngineLifecycleListener(@NonNull
                                                              FlutterEngine.EngineLifecycleListener engineLifecycleListener)

      Removes the given `engineLifecycleListener`, which was previously added using `addIsDisplayingFlutterUiListener(FlutterUiDisplayListener)`.

    - #### onDisplayOverlaySurface

          @UiThread
          public void onDisplayOverlaySurface(int id,
                                                        int x,
                                                        int y,
                                                        int width,
                                                        int height)

    - #### onBeginFrame

          @UiThread
          public void onBeginFrame()

    - #### onEndFrame

          @UiThread
          public void onEndFrame()

    - #### createOverlaySurface

          @UiThread
          public FlutterOverlaySurface createOverlaySurface()

    - #### destroyOverlaySurfaces

          @UiThread
          public void destroyOverlaySurfaces()

    - #### setLocalizationPlugin

          @UiThread
          public void setLocalizationPlugin(@Nullable
                                                      io.flutter.plugin.localization.LocalizationPlugin localizationPlugin)

      Sets the localization plugin that is used in various localization methods.

    - #### setDeferredComponentManager

          @UiThread
          public void setDeferredComponentManager(@Nullable
                                                            io.flutter.embedding.engine.deferredcomponents.DeferredComponentManager deferredComponentManager)

      Sets the deferred component manager that is used to download and install split features.

    - #### requestDartDeferredLibrary

          @UiThread
          public void requestDartDeferredLibrary(int loadingUnitId)

      Called by dart to request that a Dart deferred library corresponding to loadingUnitId be downloaded (if necessary) and loaded into the dart vm.

      This method delegates the task to DeferredComponentManager, which handles the download and loading of the dart library and any assets.

      Parameters:
        `loadingUnitId` - The loadingUnitId is assigned during compile time by gen_snapshot and is automatically retrieved when loadLibrary() is called on a dart deferred library.

    - #### loadDartDeferredLibrary

          @UiThread
          public void loadDartDeferredLibrary(int loadingUnitId,
                                                        @NonNull
                                                        String[] searchPaths)

      Searches each of the provided paths for a valid Dart shared library .so file and resolves symbols to load into the dart VM.

      Successful loading of the dart library completes the future returned by loadLibrary() that triggered the install/load process.

      Parameters:
        `loadingUnitId` - The loadingUnitId is assigned during compile time by gen_snapshot and is automatically retrieved when loadLibrary() is called on a dart deferred library. This is used to identify which Dart deferred library the resolved correspond to.
        `searchPaths` - An array of paths in which to look for valid dart shared libraries. This supports paths within zipped apks as long as the apks are not compressed using the `path/to/apk.apk!path/inside/apk/lib.so` format. Paths will be tried first to last and ends when a library is successfully found. When the found library is invalid, no additional paths will be attempted.

    - #### updateJavaAssetManager

          @UiThread
          public void updateJavaAssetManager(@NonNull
                                                       AssetManager assetManager,
                                                       @NonNull
                                                       String assetBundlePath)

      Adds the specified AssetManager as an APKAssetResolver in the Flutter Engine's AssetManager.

      This may be used to update the engine AssetManager when a new deferred component is installed and a new Android AssetManager is created with access to new assets.

      Parameters:
        `assetManager` - An android AssetManager that is able to access the newly downloaded assets.
        `assetBundlePath` - The subdirectory that the flutter assets are stored in. The typical value is `flutter_assets`.

    - #### deferredComponentInstallFailure

          @UiThread
          public void deferredComponentInstallFailure(int loadingUnitId,
                                                                @NonNull
                                                                String error,
                                                                boolean isTransient)

      Indicates that a failure was encountered during the Android portion of downloading a dynamic feature module and loading a dart deferred library, which is typically done by DeferredComponentManager.

      This will inform dart that the future returned by loadLibrary() should complete with an error.

      Parameters:
        `loadingUnitId` - The loadingUnitId that corresponds to the dart deferred library that failed to install.
        `error` - The error message to display.
        `isTransient` - When isTransient is false, new attempts to install will automatically result in same error in Dart before the request is passed to Android.

    - #### onDisplayPlatformView

          @UiThread
          public void onDisplayPlatformView(int viewId,
                                                      int x,
                                                      int y,
                                                      int width,
                                                      int height,
                                                      int viewWidth,
                                                      int viewHeight,
                                                      FlutterMutatorsStack mutatorsStack)

    - #### getBitmap

          @UiThread
          public Bitmap getBitmap()

    - #### notifyLowMemoryWarning

          @UiThread
          public void notifyLowMemoryWarning()

      Notifies the Dart VM of a low memory event, or that the application is in a state such that now is an appropriate time to free resources, such as going to the background.

      This is distinct from sending a SystemChannel message about low memory, which only notifies the running Flutter application.