public class FlutterJNI extends Object
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
FlutterRenderer.RenderSurface
with setRenderSurface(FlutterRenderer.RenderSurface)
To receive callbacks for certain events that occur on the native side, register listeners:
#addEngineLifecycleListener(EngineLifecycleListener)
addOnFirstFrameRenderedListener(OnFirstFrameRenderedListener)
setPlatformMessageHandler(PlatformMessageHandler)
To invoke a native method that is not associated with a platform view, invoke it statically:
String uri = FlutterJNI.nativeGetObservatoryUri();
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.
|
Constructor and Description |
---|
FlutterJNI() |
Modifier and Type | Method and Description |
---|---|
void |
addEngineLifecycleListener(FlutterEngine.EngineLifecycleListener engineLifecycleListener) |
void |
addOnFirstFrameRenderedListener(OnFirstFrameRenderedListener listener) |
void |
attachToNative(boolean isBackgroundView) |
void |
detachFromNativeAndReleaseResources() |
void |
dispatchEmptyPlatformMessage(String channel,
int responseId) |
void |
dispatchPlatformMessage(String channel,
ByteBuffer message,
int position,
int responseId) |
void |
dispatchPointerDataPacket(ByteBuffer buffer,
int position) |
void |
dispatchSemanticsAction(int id,
AccessibilityBridge.Action action) |
void |
dispatchSemanticsAction(int id,
AccessibilityBridge.Action action,
Object args) |
void |
dispatchSemanticsAction(int id,
int action,
ByteBuffer args,
int argsPosition) |
Bitmap |
getBitmap() |
void |
invokePlatformMessageEmptyResponseCallback(int responseId) |
void |
invokePlatformMessageResponseCallback(int responseId,
ByteBuffer message,
int position) |
boolean |
isAttached() |
void |
markTextureFrameAvailable(long textureId) |
static boolean |
nativeGetIsSoftwareRenderingEnabled() |
static String |
nativeGetObservatoryUri() |
void |
onSurfaceChanged(int width,
int height) |
void |
onSurfaceCreated(Surface surface) |
void |
onSurfaceDestroyed() |
void |
registerTexture(long textureId,
SurfaceTexture surfaceTexture) |
void |
removeEngineLifecycleListener(FlutterEngine.EngineLifecycleListener engineLifecycleListener) |
void |
removeOnFirstFrameRenderedListener(OnFirstFrameRenderedListener listener) |
void |
runBundleAndSnapshotFromLibrary(String[] prioritizedBundlePaths,
String entrypointFunctionName,
String pathToEntrypointFunction,
AssetManager assetManager) |
void |
setAccessibilityDelegate(FlutterJNI.AccessibilityDelegate accessibilityDelegate)
Sets the
FlutterJNI.AccessibilityDelegate for the attached Flutter context. |
void |
setAccessibilityFeatures(int flags) |
void |
setPlatformMessageHandler(PlatformMessageHandler platformMessageHandler)
Sets the handler for all platform messages that come from the attached platform view to Java.
|
void |
setRenderSurface(FlutterRenderer.RenderSurface renderSurface)
Sets the
FlutterRenderer.RenderSurface delegate for the attached Flutter context. |
void |
setSemanticsEnabled(boolean enabled) |
void |
setViewportMetrics(float devicePixelRatio,
int physicalWidth,
int physicalHeight,
int physicalPaddingTop,
int physicalPaddingRight,
int physicalPaddingBottom,
int physicalPaddingLeft,
int physicalViewInsetTop,
int physicalViewInsetRight,
int physicalViewInsetBottom,
int physicalViewInsetLeft) |
void |
unregisterTexture(long textureId) |
@UiThread public static boolean nativeGetIsSoftwareRenderingEnabled()
@UiThread public void setRenderSurface(@Nullable FlutterRenderer.RenderSurface renderSurface)
FlutterRenderer.RenderSurface
delegate for the attached Flutter context.
Flutter expects a user interface to exist on the platform side (Android), and that interface
is expected to offer some capabilities that Flutter depends upon. The FlutterRenderer.RenderSurface
interface represents those expectations.
If an app includes a user interface that renders a Flutter UI then a FlutterRenderer.RenderSurface
should be set (this is the typical Flutter scenario). If no UI is being rendered, such as a
Flutter app that is running Dart code in the background, then no registration may be necessary.
If no FlutterRenderer.RenderSurface
is registered then related messages coming from
Flutter will be dropped (ignored).@UiThread public void setAccessibilityDelegate(@Nullable FlutterJNI.AccessibilityDelegate accessibilityDelegate)
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.@UiThread public void setPlatformMessageHandler(@Nullable PlatformMessageHandler platformMessageHandler)
FlutterJNI
methods:
FlutterJNI
is also the recipient of all platform messages sent from its attached
Flutter context (AKA platform view). 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.@UiThread public void addEngineLifecycleListener(@NonNull FlutterEngine.EngineLifecycleListener engineLifecycleListener)
@UiThread public void removeEngineLifecycleListener(@NonNull FlutterEngine.EngineLifecycleListener engineLifecycleListener)
@UiThread public void addOnFirstFrameRenderedListener(@NonNull OnFirstFrameRenderedListener listener)
@UiThread public void removeOnFirstFrameRenderedListener(@NonNull OnFirstFrameRenderedListener listener)
@UiThread public void onSurfaceChanged(int width, int height)
@UiThread public void onSurfaceDestroyed()
@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)
@UiThread public void dispatchPointerDataPacket(ByteBuffer buffer, int position)
public void dispatchSemanticsAction(int id, @NonNull AccessibilityBridge.Action action)
public void dispatchSemanticsAction(int id, @NonNull AccessibilityBridge.Action action, @Nullable Object args)
@UiThread public void dispatchSemanticsAction(int id, int action, ByteBuffer args, int argsPosition)
@UiThread public void setSemanticsEnabled(boolean enabled)
@UiThread public void setAccessibilityFeatures(int flags)
@UiThread public void registerTexture(long textureId, SurfaceTexture surfaceTexture)
@UiThread public void markTextureFrameAvailable(long textureId)
@UiThread public void unregisterTexture(long textureId)
public boolean isAttached()
@UiThread public void attachToNative(boolean isBackgroundView)
@UiThread public void detachFromNativeAndReleaseResources()
@UiThread public void runBundleAndSnapshotFromLibrary(@NonNull String[] prioritizedBundlePaths, @Nullable String entrypointFunctionName, @Nullable String pathToEntrypointFunction, @NonNull AssetManager assetManager)
@UiThread public void dispatchEmptyPlatformMessage(String channel, int responseId)
@UiThread public void dispatchPlatformMessage(String channel, ByteBuffer message, int position, int responseId)
@UiThread public void invokePlatformMessageEmptyResponseCallback(int responseId)
@UiThread public void invokePlatformMessageResponseCallback(int responseId, ByteBuffer message, int position)