Questo esempio illustra hello-jni, un'applicazione C/C++ minima creata con l'NDK. Questo esempio si trova nella directory hello-jni del repository ndk-samples, all'interno del ramo android-mk.
Android.MK
Le due righe seguenti forniscono il nome del file di origine nativo, insieme al nome della libreria condivisa da compilare. Il nome completo della biblioteca compilata è libhello-jni.so
, una volta che il sistema di compilazione aggiunge il prefisso lib
e l'estensione .so
.
LOCAL_SRC_FILES := hello-jni.c LOCAL_MODULE := hello-jni
Per ulteriori informazioni sulla funzione del file Android.mk
e su come utilizzarlo, consulta
Android.mk.
Application.mk
Questa riga indica al sistema di build la CPU e l'architettura in base alle quali eseguire la build. In questo esempio, il sistema di compilazione crea per tutte le architetture supportate.
APP_ABI := all
Per ulteriori informazioni sul file Application.mk
e su come utilizzarlo, consulta
Application.mk.
Implementazione lato Java
Il file helloJNI.java
si trova in hellojni/src/com/example/hellojni/
. Chiama
una funzione per recuperare una stringa dal lato nativo, quindi la visualizza sullo schermo.
Il codice sorgente contiene tre righe di particolare interesse per l'utente NDK. Sono presentati qui nell'ordine in cui sono utilizzati, anziché per riga.
Questa chiamata di funzione carica il file .so
all'avvio dell'applicazione.
Kotlin
System.loadLibrary("hello-jni")
Java
System.loadLibrary("hello-jni");
La parola chiave native
in questa dichiarazione del metodo indica alla macchina virtuale che la funzione si trova nella libreria condivisa (ovvero è implementata sul lato nativo).
Kotlin
external fun stringFromJNI(): String
Java
public native String stringFromJNI();
Il framework Android chiama la funzione caricata e dichiarata nei passaggi precedenti, visualizzando la stringa sullo schermo.
Kotlin
tv.text = stringFromJNI()
Java
tv.setText( stringFromJNI() );
Implementazione lato C
Il file hello-jni.c
si trova in hello-jni/jni/
. Contiene una funzione che
restituisce una stringa richiesta dal lato Java. La dichiarazione della funzione è la seguente:
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
Questa dichiarazione corrisponde alla funzione nativa dichiarata nel codice sorgente Java. Il tipo di ritorno, jstring
, è un tipo di dati definito
nella
Java Native
Interface Specification. Non è in realtà una stringa, ma un
puntatore a una stringa Java.
Dopo jstring
arriva il nome della funzione, che si basa sul nome della funzione Java e sul percorso del file che la contiene. Costruiscilo
in base alle seguenti regole:
- Anteponi
Java_
. - Descrivi il percorso del file rispetto alla directory di origine di primo livello.
- Utilizza i trattini bassi al posto delle barre.
- Ometti l'estensione del file
.java
. - Dopo l'ultimo trattino basso, aggiungi il nome della funzione.
In base a queste regole, in questo esempio viene utilizzato il nome della funzione
Java_com_example_hellojni_HelloJni_stringFromJNI
. Questo nome fa riferimento a una funzione Java chiamata stringFromJNI()
, che si trova in hellojni/src/com/example/hellojni/HelloJni.java
.
JNIEnv*
è il puntatore alla VM e
jobject
è un puntatore all'oggetto this
implicito passato dal
lato Java.
La riga seguente chiama l'API VM (*env)
e le passa un valore restituito:
vale a dire la stringa richiesta dalla funzione sul lato Java.
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");