Cet exemple vous présente hello-jni, une application C/C++ minimale créée avec le NDK. Cet exemple se trouve dans le répertoire hello-jni du dépôt ndk-samples, dans la branche android-mk.
Android.mk
Les deux lignes suivantes indiquent le nom du fichier source natif, avec le nom de la bibliothèque partagée à compiler. Le nom complet de la bibliothèque compilée est libhello-jni.so
, une fois que le système de compilation a ajouté le préfixe lib
et l'extension .so
.
LOCAL_SRC_FILES := hello-jni.c LOCAL_MODULE := hello-jni
Pour en savoir plus sur le fichier Android.mk
et son utilisation, consultez Android.mk.
Application.mk
Cette ligne indique au système de compilation le processeur et l'architecture avec lesquels la compilation doit avoir lieu. Dans cet exemple, le système de compilation compile toutes les architectures compatibles.
APP_ABI := all
Pour en savoir plus sur le fichier Application.mk
et sur son utilisation, consultez Application.mk.
Implémentation côté Java
Le fichier helloJNI.java
se trouve dans hellojni/src/com/example/hellojni/
. Il appelle une fonction pour récupérer une chaîne du côté natif, puis l'affiche à l'écran.
Le code source contient trois lignes présentant un intérêt particulier pour l'utilisateur du NDK. Elles apparaissent dans l'ordre dans lequel elles sont utilisées, plutôt que selon l'ordre des lignes.
Cet appel de fonction charge le fichier .so
au démarrage de l'application.
Kotlin
System.loadLibrary("hello-jni")
Java
System.loadLibrary("hello-jni");
Le mot clé native
de cette déclaration de méthode indique à la machine virtuelle que la fonction se trouve dans la bibliothèque partagée (autrement dit, qu'elle est implémentée du côté natif).
Kotlin
external fun stringFromJNI(): String
Java
public native String stringFromJNI();
Le framework Android appelle la fonction chargée et déclarée lors des étapes précédentes, en affichant la chaîne à l'écran.
Kotlin
tv.text = stringFromJNI()
Java
tv.setText( stringFromJNI() );
Implémentation côté C
Le fichier hello-jni.c
se trouve dans hello-jni/jni/
. Il contient une fonction qui renvoie une chaîne demandée par le côté Java. La déclaration de la fonction est la suivante :
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
Cette déclaration correspond à la fonction native déclarée dans le code source Java. Le type renvoyé, jstring
, est un type de données défini dans la spécification de l'interface native Java. Il ne s'agit pas d'une chaîne, mais d'un pointeur vers une chaîne Java.
Après jstring
, vient le nom de la fonction. Il est basé sur le nom de la fonction Java et sur le chemin d'accès au fichier correspondant. Créez-le selon les règles suivantes :
- Faites-le précéder de
Java_
. - Décrivez le chemin d'accès du fichier par rapport au répertoire source de premier niveau.
- Utilisez des traits de soulignement à la place des barres obliques.
- Omettez l'extension de fichier
.java
. - Ajoutez le nom de la fonction après le dernier trait de soulignement.
Cet exemple, qui respecte ces règles, utilise le nom de fonction Java_com_example_hellojni_HelloJni_stringFromJNI
. Ce nom fait référence à une fonction Java appelée stringFromJNI()
, qui réside dans hellojni/src/com/example/hellojni/HelloJni.java
.
JNIEnv*
est le pointeur vers la VM, et jobject
est un pointeur vers l'objet this
implicite transmis à partir du côté Java.
La ligne suivante appelle l'API VM (*env)
et lui transmet une valeur renvoyée, à savoir la chaîne demandée par la fonction Java.
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");