In diesem Beispiel wird hello-jni beschrieben, eine minimale C/C++-Anwendung, die mit dem NDK erstellt wurde. Dieses Beispiel befindet sich im Verzeichnis hello-jni des ndk-samples-Repositorys im android-mk-Branch.
Android.mk
Die folgenden beiden Zeilen enthalten den Namen der nativen Quelldatei sowie den Namen der zu erstellenden freigegebenen Bibliothek. Der vollständige Name der erstellten Bibliothek ist libhello-jni.so
, sobald das Build-System das Präfix lib
und die Erweiterung .so
hinzugefügt hat.
LOCAL_SRC_FILES := hello-jni.c LOCAL_MODULE := hello-jni
Weitere Informationen zur Funktion und Verwendung der Datei Android.mk
finden Sie unter Android.mk.
Application.mk
Diese Zeile gibt dem Build-System die CPU und die Architektur an, für die es erstellt werden soll. In diesem Beispiel führt das Build-System einen Build für alle unterstützten Architekturen aus.
APP_ABI := all
Weitere Informationen zur Datei Application.mk
und ihrer Verwendung finden Sie unter Application.mk.
Java-seitige Implementierung
Die Datei helloJNI.java
befindet sich in hellojni/src/com/example/hellojni/
. Es ruft eine Funktion auf, um einen String von der nativen Seite abzurufen, und zeigt ihn dann auf dem Bildschirm an.
Der Quellcode enthält drei Zeilen, die für NDK-Nutzer von besonderem Interesse sind. Sie werden hier in der Reihenfolge ihrer Verwendung und nicht in der Zeilenreihenfolge aufgeführt.
Durch diesen Funktionsaufruf wird die Datei .so
beim Start der Anwendung geladen.
Kotlin
System.loadLibrary("hello-jni")
Java
System.loadLibrary("hello-jni");
Das Keyword native
in dieser Methodendeklaration teilt der virtuellen Maschine mit, dass sich die Funktion in der freigegebenen Bibliothek befindet (d. h. nativ implementiert ist).
Kotlin
external fun stringFromJNI(): String
Java
public native String stringFromJNI();
Das Android-Framework ruft die Funktion auf, die in den vorherigen Schritten geladen und deklariert wurde, und zeigt den String auf dem Bildschirm an.
Kotlin
tv.text = stringFromJNI()
Java
tv.setText( stringFromJNI() );
C-seitige Implementierung
Die Datei hello-jni.c
befindet sich unter hello-jni/jni/
. Sie enthält eine Funktion, die einen String zurückgibt, den von der Java-Seite angefordert wurde. Die Funktionsdeklaration sieht so aus:
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
Diese Deklaration entspricht der nativen Funktion, die im Java-Quellcode deklariert wurde. Der Rückgabetyp jstring
ist ein Datentyp, der in der Java Native Interface Specification definiert ist. Es ist eigentlich kein String, sondern ein Verweis auf einen Java-String.
Nach jstring
folgt der Funktionsname, der auf dem Namen der Java-Funktion und dem Pfad zur Datei basiert, die sie enthält. Erstellen Sie sie gemäß den folgenden Regeln:
- Stellen Sie
Java_
voran. - Geben Sie den Dateipfad relativ zum Quellverzeichnis der obersten Ebene an.
- Verwenden Sie Unterstriche anstelle von Schrägstrichen.
- Lassen Sie die Dateiendung
.java
weg. - Fügen Sie nach dem letzten Unterstrich den Funktionsnamen an.
Gemäß diesen Regeln wird in diesem Beispiel der Funktionsname Java_com_example_hellojni_HelloJni_stringFromJNI
verwendet. Dieser Name bezieht sich auf eine Java-Funktion namens stringFromJNI()
, die sich in hellojni/src/com/example/hellojni/HelloJni.java
befindet.
JNIEnv*
ist der Verweis auf die VM und jobject
ist ein Verweis auf das implizite this
-Objekt, das von der Java-Seite übergeben wird.
In der folgenden Zeile wird die VM-API (*env)
aufgerufen und ihr ein Rückgabewert übergeben: der String, der von der Funktion auf Java-Seite angefordert wurde.
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");