Esempio: hello-jni

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 ".");