jni library

Package jni provides dart bindings for the Java Native Interface (JNI) on Android and desktop platforms.

It's intended as a supplement to the JNIgen tool, a Java wrapper generator using JNI. The goal of this package is to provide sufficiently complete and ergonomic access to underlying JNI APIs.

Therefore, some understanding of JNI is required to use this module.

Java VM

On Android, the existing JVM is used, a new JVM needs to be spawned on flutter desktop & standalone targets.

if (!Platform.isAndroid) {
  Jni.spawn();
}

Dart standalone support

On dart standalone target, we unfortunately have no mechanism to bundle the wrapper libraries with the executable. Thus it needs to be explicitly placed in a accessible directory and provided as an argument to Jni.spawn.

This module depends on a shared library written in C. Therefore on dart standalone:

  • Run dart run jni:setup to build the shared library. This command builds all dependency libraries with native code (package:jni and JNIgen-generated libraries if any).

The default output directory is build/jni_libs, which can be changed using -B switch.

  • Provide the location of library to Jni.spawn call.

JNIEnv

Jni.env provides a thin wrapper over JNIEnv* which can be used from across threads, and always returns JNI global references. This is needed because Dart doesn't make guarantees about even the straight-line code being scheduled on the same thread.

Debugging

Debugging JNI errors is hard in general.

  • On desktop platforms, methods on Jni.env such as Jni.env.ExceptionDescribe() can be used to print any pending exception to stdout.
  • On Android, things are slightly easier since CheckJNI is usually enabled in debug builds. If you are not getting clear stack traces on JNI errors, check the Android NDK page on how to enable CheckJNI using ADB.
  • As a rule of thumb, when there's a NoClassDefFound / NoMethodFound error, first check your class and method signatures for typos. Another common reason for NoClassDefFound error is missing classes in classpath.

This library provides classes and functions for JNI interop from Dart.

Classes

$JClass$Type$
$JCollection<$E extends JObject?>
$JIterator<$E extends JObject?>
$JList<$E extends JObject?>
$JMap<$K extends JObject?, $V extends JObject?>
$JMap$JEntry<$K extends JObject?, $V extends JObject?>
$JSet<$E extends JObject?>
Arena
An Allocator which frees all allocations at the same time.
jboolean
The Java boolean primitive type.
jbooleanType
jbyte
The Java byte primitive type.
jbyteType
jchar
The Java char primitive type.
jcharType
JClass
A high level wrapper over a JNI class reference.
jdouble
The Java double primitive type.
jdoubleType
jfloat
The Java float primitive type.
jfloatType
JGlobalReference
A managed JNI global reference.
JImplementer
A builder that builds proxy objects that implement one or more interfaces.
JInstanceMethodId
A thin wrapper over a JMethodIDPtr of an instance method.
jint
The Java int primitive type.
jintType
jlong
The Java long primitive type.
jlongType
Jni
Utilities to spawn and manage JNI.
JObject
A high-level wrapper for JNI global object reference.
JPrimitive
Base class for Java primitive types.
JReference
An abstract reference to a Java object managed by JNI.
jshort
The Java short primitive type.
jshortType
JType<T extends JObject?>
Represents the type of a JObject.
JValueByte
Use this class as wrapper to convert an integer to Java byte in jvalues method.
JValueChar
Use this class as wrapper to convert an integer to Java char in jvalues method.
JValueFloat
Use this class as wrapper to convert an double to Java float in jvalues method.
JValueInt
Use this class as wrapper to convert an integer to Java int in jvalues method.
JValueShort
Use this class as wrapper to convert an integer to Java short in jvalues method.
jvoid
The Java void primitive type.
jvoidType

Mixins

JAccessible<JavaT, DartT>
Able to be the type of a field that can be get and set.
JCallable<JavaT, DartT>
Able to be a return type of a method that can be called.

Extension Types

JArray
JArrayList
from: java.util.ArrayList
JBoolean
from: java.lang.Boolean
JBooleanArray
A fixed-length array of Java Boolean.
JBuffer
A container for data of a specific primitive type.
JByte
from: java.lang.Byte
JByteArray
A fixed-length array of Java Byte.
JByteBuffer
A byte JBuffer.
JCharacter
from: java.lang.Character
JCharArray
A fixed-length array of Java Char.
JCollection
from: java.util.Collection
JConstructorId
A thin wrapper over a JMethodIDPtr of a constructor.
JDouble
from: java.lang.Double
JDoubleArray
A fixed-length array of Java Double.
JFloat
from: java.lang.Float
JFloatArray
A fixed-length array of Java Float.
JHashMap
from: java.util.HashMap
JHashSet
from: java.util.HashSet
JInstanceFieldId
A thin wrapper over a JFieldIDPtr of an instance field.
JIntArray
A fixed-length array of Java Int.
JInteger
from: java.lang.Integer
JIterator
from: java.util.Iterator
JList
from: java.util.List
JLong
from: java.lang.Long
JLongArray
A fixed-length array of Java Long.
JMap
from: java.util.Map
JNumber
from: java.lang.Number
JSet
from: java.util.Set
JShort
from: java.lang.Short
JShortArray
A fixed-length array of Java Short.
JStaticFieldId
A thin wrapper over a JFieldIDPtr of a static field.
JStaticMethodId
A thin wrapper over a JMethodIDPtr of a static method.
JString
from: java.lang.String

Extensions

AdditionalEnvMethods on GlobalJniEnv
BoolToJava on bool
DartIterableToJList on Iterable<Object?>
DartIterableToJSet on Iterable<Object?>
DartListToJArray on List<Object?>
DartMapToJMap on Map<Object?, Object?>
DoubleToJava on double
IntToJava on int
JArrayList$$Methods on JArrayList<$E>
JArrayToDartList on JArray<JObject?>
JArrayToList on JArray<E>
JBoolean$$Methods on JBoolean
JBooleanArrayToList on JBooleanArray
JBooleanExtension on JBoolean
JByte$$Methods on JByte
JByteArrayToList on JByteArray
JByteExtension on JByte
JCharacter$$Methods on JCharacter
JCharacterExtension on JCharacter
JCharArrayToList on JCharArray
JCollection$$Methods on JCollection<$E>
JDouble$$Methods on JDouble
JDoubleArrayToList on JDoubleArray
JDoubleExtension on JDouble
JFloat$$Methods on JFloat
JFloatArrayToList on JFloatArray
JFloatExtension on JFloat
JHashMap$$Methods on JHashMap<$K, $V>
JHashSet$$Methods on JHashSet<$E>
JIntArrayToList on JIntArray
JInteger$$Methods on JInteger
JIntegerExtension on JInteger
JIterator$$Methods on JIterator<$E>
JIteratorToAdapter on JIterator<E>
JList$$Methods on JList<$E>
JListToAdapter on JList<E>
JListToDartList on JList<JObject?>
JLong$$Methods on JLong
JLongArrayToList on JLongArray
JLongExtension on JLong
JMap$$Methods on JMap<$K, $V>
JMapToAdapter on JMap<K, V>
JMapToDartMap on JMap<JObject?, JObject?>
JNumber$$Methods on JNumber
JNumberExtension on JNumber
JObjectUseExtension on T
JSet$$Methods on JSet<$E>
JSetToAdapter on JSet<E>
JSetToDartSet on JSet<JObject?>
JShort$$Methods on JShort
JShortArrayToList on JShortArray
JShortExtension on JShort
JString$$Methods on JString
JStringExtension on JString
ToJavaList on Iterable<E>
ToJavaMap on Map<K, V>
ToJavaSet on Iterable<E>
ToJStringMethod on String
Uint8ListToJava on Uint8List

Properties

jNullReference → JReference
A singleton JReference representing a Java null reference.
final

Functions

toDartObject(JObject javaObject, {Object convertOther(JObject) = _defaultDartConverter}) → Object
Converts a Java object to the corresponding Dart object.
toJObject(Object dartObject, {JObject convertOther(Object) = _defaultJObjectConverter}) → JObject
Converts a Dart object to the corresponding Java object.
toJValues(List args, {required Allocator allocator}) → Pointer<JValue>
Converts passed arguments to JValue array for use in methods that take arguments.
toNullableDartObject(JObject? javaObject, {Object convertOther(JObject) = _defaultDartConverter}) → Object?
Converts a nullable Java object to the corresponding Dart object.
toNullableJObject(Object? dartObject, {JObject convertOther(Object) = _defaultJObjectConverter}) → JObject?
Converts a nullable Dart object to the corresponding Java object.
using<R>(R computation(Arena arena), [Allocator wrappedAllocator = calloc]) → R
Runs computation with a new Arena, and releases all allocations at the end.

Exceptions / Errors

CastError
Error thrown when casting between incompatible JObject subclasses.
DoubleReleaseError
Error thrown when attempting to release an already-released JNI reference.
DynamicLibraryLoadError
Error thrown when loading a dynamic library fails.
HelperNotFoundError
Error thrown when the JNI helper shared library cannot be found.
JniArgumentError
Error representing invalid arguments passed to a JNI function.
JniError
Represents JNI errors that might be returned by methods like CreateJavaVM.
JniGenericError
Error representing a generic JNI failure.
JniNewStringException
Exception thrown when converting a Dart string to a Java string fails.
JniOutOfMemoryError
Error representing a JNI out of memory condition.
JniThreadDetachedError
Error representing a thread detached from the Java VM.
JniVersionError
Error representing a JNI version error.
JniVmExistsError
Error representing that a Java VM has already been created.
JNullError
Error thrown when an unexpected null reference is encountered.
JThrowable
A high-level wrapper for JNI global object reference of a java.lang.Throwable.
NoJvmInstanceError
Error thrown when attempting an operation that requires a JVM instance, but none is running.
NoSuchMethodError
Error thrown when a Java method or field cannot be found.
UseAfterReleaseError
Error thrown when an operation is performed on an object whose underlying JNI reference has been released.