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.
Prerequisites
- JDK
- Maven
- (Optional) clang-formatto format the generated C bindings
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.
output:
  c:
    library_name: example
    path: src/example/
  dart:
    path: lib/example.dart
    structure: single_file
source_path:
  - 'java/'
classes:
  - 'dev.dart.Example'
path specifies the path for the generated c and 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/Example.java 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 (and C) 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 libraries for jni and the generated C files. 
The Java sources also must be compiled. To do so, run:
$ dart run jni:setup -p jni -s src/example
$ javac java/dev/dart/Example.java
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:
| Example | Description | 
|---|---|
| in_app_java | Demonstrates how to include custom Java code in a Flutter application and call it use jnigen. | 
| pdfbox_plugin | Example of a Flutter plugin that provides bindings to the Apache PDFBox library. | 
| notification_plugin | Example of a reusable Flutter plugin with custom Java code that uses Android libraries. |