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) {
  // Spin up a JVM instance with custom classpath etc..
  Jni.spawn(/* options */);
}

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

GlobalJniEnv type 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 hard in general.

  • On desktop platforms you can use JniEnv.ExceptionDescribe 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

Arena
An Allocator which frees all allocations at the same time.
CallbackResult
GlobalJniEnv
Wraps over Pointer
GlobalJniEnvStruct
JArray<E>
JArrayType<E>
JavaVMInitArgs
JavaVMOption
JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no longer supported.)
JBoolean
jboolean
JBooleanType
jbooleanType
JBuffer
A container for data of a specific primitive type.
JBufferType
JByte
jbyte
JByteBuffer
A byte JBuffer.
JByteBufferType
JByteType
jbyteType
jchar
JCharacter
JCharacterType
jcharType
JClass
A high level wrapper over a JNI class reference.
JDouble
jdouble
JDoubleType
jdoubleType
jfieldID_
jfloat
JFloat
jfloatType
JFloatType
JGlobalReference
A managed JNI global reference.
jint
JInteger
JIntegerType
jintType
JIterator<$E extends JObject>
JIteratorType<$E extends JObject>
JList<$E extends JObject>
JListType<$E extends JObject>
JLong
jlong
JLongType
jlongType
JMap<$K extends JObject, $V extends JObject>
JMapType<$K extends JObject, $V extends JObject>
jmethodID_
Jni
Utilities to spawn and manage JNI.
JniAccessors
Wraps over the function pointers in JniAccessorsStruct and exposes them as methods.
JniAccessorsStruct
This struct contains functions which wrap method call / field access conveniently along with exception checking.
JniBooleanValues
This file re-exports some JNI constants as enum, because they are not currently being included when they are in macro form.
JniBufferWriteBack
JniCallType
Types used by JNI API to distinguish between primitive types.
JniClassLookupResult
Similar to JniResult but for class lookups.
JniErrorCode
JNIInvokeInterface
JNI invocation interface.
JNINativeInterface
Table of interface function pointers.
JNINativeMethod
JniPointerResult
Similar to JniResult but for method/field ID lookups.
JniResult
Result type for use by JNI.
JniVersions
JNumber
JNumberType
JObject
A high-level wrapper for JNI global object reference.
JObjectRefType
JObjectType
JObjType<T extends JObject>
JPrimitive
JReference
JSet<$E extends JObject>
JSetType<$E extends JObject>
jshort
JShort
JShortType
jshortType
JString
JStringType
JType<JavaT>
JValue
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
jvoidType

Mixins

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

Extension Types

JConstructorId
A thin wrapper over a JMethodIDPtr of a constructor.
JInstanceFieldId
A thin wrapper over a JFieldIDPtr of an instance field.
JInstanceMethodId
A thin wrapper over a JMethodIDPtr of an instance method.
JStaticFieldId
A thin wrapper over a JFieldIDPtr of an static field.
JStaticMethodId
A thin wrapper over a JMethodIDPtr of a static mehtod.

Constants

DART_JNI_SINGLETON_EXISTS → const int

Properties

jNullReference JReference
final
nullptr Pointer<Never>
Represents a pointer into the native C memory corresponding to 'NULL', e.g. a pointer with address 0.
final

Functions

lowestCommonSuperType(List<JObjType<JObject>> types) JObjType<JObject>
toJValues(List args, {required Allocator allocator}) Pointer<JValue>
Converts passed arguments to JValue array for use in methods that take arguments.
using<R>(R computation(Arena), [Allocator wrappedAllocator = calloc]) → R
Runs computation with a new Arena, and releases all allocations at the end.