Java interop using package:jnigen

Dart mobile, command-line, and server apps running on the Dart Native platform, on Android, Windows, macOS, and Linux can use package:jni and package:jnigen to call Java and Kotlin APIs.

package:jni allows Dart code to interact with Java through JNI. However, doing so involves a lot of boilerplate code, so you can use package:jnigen to automatically generate the Dart bindings for a given Java API.

You can compile Kotlin to Java bytecode, allowing package:jnigen to generate bindings for Kotlin as well.

Simple Java example


This guide walks you through an example that uses package:jnigen to generate bindings for a simple class.



Configure jnigen


First, add package:jni as a dependency and package:jnigen as a dev dependency.

$ dart pub add jni dev:jnigen

Next, create a top-level file called jnigen.yaml. This file contains the configuration for generating the bindings.

    path: lib/example.dart
    structure: single_file

  - 'java/'
  - 'dev.dart.Example'

path specifies the path for the generated dart bindings.

source_path specifies the path of the Java source file that you want to generate bindings for, and classes specifies the Java class.

java/dev/dart/ contains a very simple class, which has a public static method called sum:

package dev.dart;

public class Example {
  public static int sum(int a, int b) {
    return a + b;

Generate the Dart bindings


To generate the Dart bindings, run jnigen and specify the config file using the --config option:

$ dart run jnigen --config jnigen.yaml

In this example, this generates lib/example.dart, just as you specified in jnigen.yaml.

This file contains a class called Example, which has a static method called sum, just like the Java file.

Use the bindings


Now you're ready to load and interact with the generated library. The example app, bin/sum.dart, gets two numbers as arguments and prints their sum. Using the Example.sum method is identical to Java.

// a and b are integer arguments
print(Example.sum(a, b));

Run the example


Before running the example, you must build the dynamic library for jni. The Java sources also must be compiled. To do so, run:

$ dart run jni:setup
$ javac java/dev/dart/

Now you can run the example:

$ dart run jnigen_example:sum 17 25

Which outputs 42!

More examples


The following are some more comprehensive examples of using package:jnigen:

in_app_javaDemonstrates how to include custom Java code in a Flutter application and call it use jnigen.
pdfbox_pluginExample of a Flutter plugin that provides bindings to the Apache PDFBox library.
notification_pluginExample of a reusable Flutter plugin with custom Java code that uses Android libraries.