# jni 1.0.0

A library to access JNI from Dart and Flutter that acts as a support library for package:jnigen.




## Installing
```
export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add 'jni:1.0.0'
```
Published: 2026-04-01T00:07:50.862602Z
Expected archive SHA-256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f

Available in cache; verification: upstream_checksum
## Direct dependencies
- args: ^2.5.0
- collection: ^1.19.1
- ffi: ^2.1.3
- meta: ^1.15.0
- package_config: ^2.1.0
- path: ^1.9.0
- plugin_platform_interface: ^2.1.8

## Package README (untrusted upstream documentation)
[![Build Status](https://github.com/dart-lang/native/actions/workflows/jnigen.yaml/badge.svg)](https://github.com/dart-lang/native/actions/workflows/jnigen.yaml)
[![Coverage Status](https://coveralls.io/repos/github/dart-lang/native/badge.svg?branch=main)](https://coveralls.io/github/dart-lang/native?branch=main)
[![pub package](https://img.shields.io/pub/v/jni.svg)](https://pub.dev/packages/jni)
[![package publisher](https://img.shields.io/pub/publisher/jni.svg)](https://pub.dev/packages/jni/publisher)

# JNI

This is a support library to access JNI from Dart / Flutter code. This provides the common infrastructure to bindings generated by [JNIgen](https://pub.dev/packages/jnigen), as well as some utility methods.

This library contains:

* Functions to access the JNIEnv and JavaVM variables from JNI, and wrapper functions to those provided by JNI. JNIEnv is exposed via `GlobalJniEnv` type which provides a thin abstraction over JNIEnv, so that it can be used from multiple threads.
* Functions to spawn a JVM on desktop platforms (`Jni.spawn`).
* `JObject` class, which provides base class for classes generated by JNIgen.
* Commonly used Java classes like `JList`, `JMap`, `JInteger`, ...

Apart from being the base library for code generated by JNIgen this can also be used for one-off uses of the JNI and debugging. __To generate type-safe bindings from Java libraries, use JNIgen.__

## Documentation
The test/ directory contains files with comments explaining the basics of this module, and the example/ directory contains a flutter example which also touches some Android-specifics.

Using this library assumes some familiarity with JNI - it's threading model and object references, among other things.

## Migrating to 0.8.0

Check the [changelog](https://github.com/dart-lang/native/blob/main/pkgs/jni/CHANGELOG.md#080-wip).

The API for standalone use of `package:jni` (without `package:jnigen`) has
changed to use `JClass.forName` for finding classes. Find the methods and fields
by accessing them from the retrieved `JClass`. For example find an instance
method with a name and a signature using `jClass.instanceMethodId`. Then you can
`call` the resulting `JInstanceMethodId` to call the instance method.

## Changelog
## 1.0.0

- **Breaking Change**: The Flutter specific APIs `Jni.androidApplicationContext`
  and `Jni.androidActivity(int engineId)` have been moved to a new
  package:jni_flutter. If you are using package:jni on Android you may need to
  add this new package as a dependency.
- **Breaking Change**: All Java wrapper classes have been migrated to extension
  types. The main effects are:
  - All collections (`JList`, `JMap` etc) are now direct code generated wrappers
    around the Java objects, so are less Darty. Instead there are now Darty
    adapter classes you can access via `asDart()`.
  - No more nullable `JType` classes, only `JType` classes, and the `JType`
    class is simplified.
  - It is no longer necessary to pass around the `JType` in many cases where it
    used to be required.
- Added `Jni.captureStackTraceOnRelease` which defaults to `false`. When this is
  set, the stack traces of the release points will be stored for `JObject`s to
  help debug `DoubleReleaseError` and `UseAfterReleaseError`s. This includes the
  points where `JObject`s have been registered to be released by an `arena` via
  `JObject.releaseBy`.
- Changed the behavior of `JObject.releasedBy`. It now does not throw a
  `DoubleReleaseError` if the object was manually released before the end of
  arena.
- Added `JThrowable` class which inherits from `JObject` and implements
  `Exception`.
- **Breaking Change**: `JniException` has been deleted. Java exceptions are now
  thrown as `JThrowable` instead. `JThrowable` holds an actual Java exception,
  instead of just holding a string message. It's a `JObject`, so the usual
  `.isA` and `.as` methods work to cast the `JThrowable` to the underlying Java
  exception.
- **Breaking Change**: Class methods like getFoo, isFoo, and setFoo are now
  getters and setters in Dart.
- **Breaking Change**: APIs of `JBoolean`, `JByte`, `JCharacter`, `JDouble`,
  `JFloat`, `JInteger`, `JLong`, `JNumber`, `JShort`, and `JString` have changed
  to be more consistent with other APIs. For example, `JBoolean.booleanValue` is
  now `JBoolean.toDartBool`.
- Fixed [bugs](https://github.com/dart-lang/native/issues/3244) that were
  causing crashes in interfaces after app close and reopen.
- Add compile time version checks to verify consistency of package:jni's
  versions vs JNIgen's generated code.

## 0.15.2

- Do not fail `flutter build` if JDK is not found for desktop.

## 0.15.1

- **Breaking Change**: Removed the `engineId` argument from
  `Jni.androidApplicationContext` as the application context is not dependant on
  the engine ID.

## 0.15.0

- **Breaking Change**: Made `Jni.env` internal.
- **Breaking Change**: Renamed `JObjType` to `JType`.
- **Breaking Change**: Made all of the type classes internal.
- **Breaking Change**: Removed `Jni.getApplicationClassLoader()`,
  `Jni.getCurrentActivity()`, and `Jni.getCachedApplicationContext()`. Instead
  use `Jni.androidApplicationContext(engineId)` to access the application
  context and use `Jni.androidActivity(engineId)` to acccess the activity.
- Update to the latest lints.

## 0.14.2

- Fixed a bug where certain method of `JList`, `JSet`, and `JMap` did not work
  with nullable elements.
- Fixed a bug in `JList.lastIndexOf`.

## 0.14.1

- Updated `bin/setup.dart` to use Gradle instead of Maven for building Java
  sources. Added gradle executables and bootstrap jars
  [#2003](https://github.com/dart-lang/native/issues/2003)
- Added `JObject.isInstanceOf` which checks whether a `JObject` is an instance
  of a java class.
- Fixed a [bug](https://github.com/dart-lang/native/issues/1908) where Java
  interfaces implemented in on the main thread in Dart could deadlock when
  invoked from the main thread outside the context of a Dart isolate.

## 0.14.0

- Added `DynamicLibraryLoadError` which is thrown when the dynamic library fails
  to load. `HelperNotFoundError` will only be thrown when the helper library
  cannot be found.
- Update the README.md to include info about generating bindings for built-in
  java types.
- Do not require a `dylibDir` when running `Jni.spawn` from Dart standalone,
  instead use the default value of `build/jni_libs`.
- Added `JArray.of`, which allows a `JArray` to be constructed from an
  `Iterable`.
- Added `JObject.isA`, which checks whether a `JObject` is an instance of a java
  typeclass.
- Do not require JAWT when building for desktop.
- Added `JByteArray.from`, which allows a `JByteArray` to be constructed from an
  `Iterable<int>`.

## 0.13.0

- **Breaking Change**: Separated primitive arrays from object arrays.
  Previously, a primitive array like an array of bytes was typed
  `JArray<jbyte>`. Now `JArray<T>` only accepts `JObject`s as types and
  primitive arrays like arrays of bytes have their own types such as
  `JByteArray`.

  This enables all arrays to implement `Iterable` which makes it possible to use
  them in a for-loop or use methods such as `map` on them.

- Added nullable type classes for all Java objects.
- Fixed a problem where interfaces implemented in Dart would crash when calling
  the default object methods: `equals`, `hashCode`, and `toString`.

## 0.12.2

- Added `JniUtils.fromReferenceAddress` which helps with sending `JObject`s
  through method channels. You can send the address of the pointer as `long` and
  reconstruct the class using the helper method.
- Fixed a bug where it would be possible for a type class inference to fail.
- Return 'null' when calling `toString` on a null object.

## 0.12.0

- **Breaking Change**: Renamed `castTo` to `as`.
- Renamed library `internal_helpers_for_jnigen` to `_internal`.
- Using 16KB page size to support Android 15.
- Added `JImplementer` which enables building an object that implements multiple
  Java interfaces.

## 0.11.0

- **Breaking Change** Removed `Jni.accessors`.
- Made most `Jni.env` methods into leaf functions to speed up their execution.
- Removed the dependency on `kotlin_gradle_plugin`.

## 0.10.1

- Fixed an issue with `JObject.castTo` where the type checking could fail in
  debug mode.
- Used `package:dart_flutter_team_lints`.

## 0.9.3

- Added lifetime event handling for the thread-local JNI env. Now
  `jvm.DetachNativeThread` is called when the thread detaches as recommended
  [here](https://developer.android.com/training/articles/perf-jni#threads).
- Removed `JValueChar.fromString` constructor.

## 0.9.2

- Bumped `minSdk` to 21.

## 0.9.1

- Fixed compilation on macOS for consumers that don't use JNI on macOS (which is
  still not supported) ([#1122](https://github.com/dart-lang/native/pull/1122)).

## 0.9.0

- **Breaking Change**
  ([#1004](https://github.com/dart-lang/native/issues/1004)): Changed the return
  type `operator []` of `JArray<jchar>` to `int` instead of `String`. Similarly,
  change the argument type of `operator []=` to accept `int`.
- Added `getRange` method to `JArray` of primitive types that returns a
  `TypedData` list depending on the kind of the array.
- Improved the performance of `JArray`'s `setRange` and `operator []=`.

## 0.8.0

- **Breaking Change** ([#981](https://github.com/dart-lang/native/issues/981)):

  - `JObject.reference` now returns a `JReference` instead of `Pointer<Void>`.
  - `.fromRef` constructors are now called `.fromReference` and they take a
    `JReference` instead of `Pointer<Void>`.
  - `JObject` reflective field retrieving and method calling methods are
    removed. Use `JClass` API instead.
  - The following `Jni.accessors` methods have been removed:

    - `getClassOf`
    - `getMethodIDOf`
    - `getStaticMethodIDOf`
    - `getFieldIDOf`
    - `getStaticFieldIDOf`
    - `newObjectWithArgs`
    - `callMethodWithArgs`
    - `callStaticMethodWithArgs`

    Instead use the `JClass` API.

  - `Jni.findJClass` is replaced with `JClass.forName(String name)`
  - `JClass` has been refactored. Instead of directly calling methods, getting
    and setting fields, use `JClass.instanceMethodId`, `JClass.staticMethodId`,
    `JClass.constructorId`, `JClass.instanceFieldId`, and `JClass.staticFieldId`
    to first get access to the member.
  - Renamed `JObject.getClass()` to `JObject.jClass`.
  - Removed `Jni.deleteAllRefs`.

- **Breaking Change** ([#548](https://github.com/dart-lang/native/issues/548)):
  Converted various `Exception`s into `Error`s:
  - `UseAfterReleaseException` -> `UseAfterReleaseError`
  - `DoubleReleaseException` -> `DoubleReleaseError`
  - `SpawnException` -> `JniError` (It's now a `sealed class`)
  - `JNullException` -> `JNullError`
  - `InvalidCallTypeException` -> `InvalidCallTypeError`
  - `HelperNotFoundException` -> `HelperNotFoundError`
  - `JvmExistsException` -> `JniVmExistsError`
  - `NoJvmInstanceException` -> `NoJvmInstanceError`
- **Breaking Change**: Removed `InvalidJStringException`.
- **Breaking Change**: `JType` is now `sealed`.
- **Breaking Change**: Primitive types and their type classes are now `final`.
- **Breaking Change**: `JArray.filled` now uses the generated type class of the
  `fill` object and not its Java runtime type.
- `JObject`s now check the types using `instanceof` in debug mode when using
  `castTo`.
- **Breaking Change**: `Jni.initDLApi()` is removed.
- Added the ability to share `JObject`s across isolates.
  ```dart
  // This now works.
  final foo = 'foo'.toJString();
  Isolate.run(() {
    // `foo` is usable from another isolate.
    print(foo);
  });
  ```

## 0.7.3

- Fixed a bug where `get(Static)MethodID` and `get(Static)FieldID` could access
  null and throw.

## 0.7.2

- Fixed a bug where reading non-null terminated strings would overflow.
- Use `package:dart_flutter_team_lints`.

## 0.7.1

- Removed macOS Flutter plugin until package:jni supports it
  ([#780](https://github.com/dart-lang/native/issues/780)).

## 0.7.0

- **Breaking Change** ([#563](https://github.com/dart-lang/native/issues/563)):
  Added `JBuffer` and `JByteBuffer` classes as default classes for
  `java.nio.Buffer` and `java.nio.ByteBuffer` respectively.
- **Breaking Change**: Made the type classes `final`.
- Fixed a bug where `addAll`, `removeAll` and `retainAll` in `JSet` would run
  their respective operation twice.
- Fixed a bug where `JList.insertAll` would not throw the potentially thrown
  Java exception.

## 0.6.1

- Depend on the stable version of Dart 3.1.

## 0.6.0

- **Breaking Change** ([#707](https://github.com/dart-lang/native/issues/707)):
  Renamed `delete*` to `release*`.
- Added `PortProxy` and related methods used for interface implementation.
- Added the missing binding for `java.lang.Character`.

## 0.5.0

- **Breaking Change** ([#711](https://github.com/dart-lang/native/issues/711)):
  Java primitive types are now all lowercase like `jint`, `jshort`, ...
- The bindings for `java.util.Set`, `java.util.Map`, `java.util.List` and the
  numeric types like `java.lang.Integer`, `java.lang.Boolean`, ... are now
  included in `package:jni`.

## 0.4.0

- Type classes now have `superCount` and `superType` getters used for type
  inference.

## 0.3.0

- Added `PortContinuation` used for `suspend fun` in Kotlin.
- `dartjni` now depends on `dart_api_dl.h`.

## 0.2.1

- Added `.clang-format` to pub.

## 0.2.0

- Added array support
- Added generic support
- `JniX` turned into `JX` for a more terse code.

## 0.1.1

- Windows support for running tests and examples on development machines.

## 0.1.0

- Initial version: Android and Linux support, JObject API







 
