# Java Native Interface APIs in Unity

> Learn about the Java Native Interface APIs in Unity that you can use to call Java/Kotlin code from C# scripts.

Unity provides low-level and high-level [Java Native Interface](https://developer.android.com/training/articles/perf-jni) (JNI) APIs that allow you to interact with Java code from C# scripts.

## Low-level API

The low-level [AndroidJNI](/engine/6000.6/script-reference/unityengine/androidjni.md) class wraps JNI calls and provides static methods that directly map to JNI methods. The [AndroidJNIHelper](/engine/6000.6/script-reference/unityengine/androidjnihelper.md) API provides helper functionality that's primarily used by the high-level API, but they can be useful in certain situations.

## High-level API

The high-level [AndroidJavaObject](/engine/6000.6/script-reference/unityengine/androidjavaobject.md), [AndroidJavaClass](/engine/6000.6/script-reference/unityengine/androidjavaclass.md), and [AndroidJavaProxy](/engine/6000.6/script-reference/unityengine/androidjavaproxy.md) classes automate a lot of tasks required for JNI calls. They also use caching to make calls to Java faster. The combination of `AndroidJavaObject` and `AndroidJavaClass` is built on top of `AndroidJNI` and `AndroidJNIHelper`, but they also contain additional functionality such as static methods that you can use to access static members of Java classes.

Additionally, Unity provides the [AndroidApplication](/engine/6000.6/script-reference/unityengine/android/androidapplication.md) class to simplify access to instances of `currentActivity`, `currentContext`, and `currentConfiguration` for your application. This class also allows you to delegate code execution on the UI or main thread based on your application's requirement.

Instances of `AndroidJavaObject` and `AndroidJavaClass` have a one-to-one mapping to an instance of [java.lang.Object](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html) and [java.lang.Class](https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html) respectively. They provide three types of interactions with Java/Kotlin code:

* [Call](/engine/6000.6/script-reference/unityengine/androidjavaobject/call.md) a method.
* [Get](/engine/6000.6/script-reference/unityengine/androidjavaobject/get.md) the value of a field.
* [Set](/engine/6000.6/script-reference/unityengine/androidjavaobject/set.md) the value of a field.

Each interaction also has a static version:

* [CallStatic](/engine/6000.6/script-reference/unityengine/androidjavaobject/callstatic.md) to call a static method.
* [GetStatic](/engine/6000.6/script-reference/unityengine/androidjavaobject/getstatic.md) to get the value of a static field.
* [SetStatic](/engine/6000.6/script-reference/unityengine/androidjavaobject/setstatic.md) to set the value of a static field.

When you get the value of a field or call a method that returns a value, you use [generics](https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics) to specify the return type. When you set the value of a field, you also use generics to specify the type of the field that you're setting. For methods that don't return a value, there's a regular, non-generic version of [Call](/engine/6000.6/script-reference/unityengine/androidjavaobject/call.md).

> **Important:**
>
> You must access any [non-primitive type](http://developer.android.com/reference/java/lang/Class.html) as an `AndroidJavaObject`. The only exception is a string which you access directly, even though they don't represent a primitive type in Java.

## Additional resources

* [Code examples: Call Java/Kotlin code from C# scripts](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp/high-level-api-code-examples.md)
* [Best practices for calling Java/Kotlin code](/engine/6000.6/manual/platform-specific/android/developing/plugins-for/plugins-java-code-from-c-sharp/call-java-kotlin-code-best-practices.md)
