Przykład: hello-jni

Ten przykład zawiera informacje o aplikacji hello-jni, czyli minimalnej aplikacji w języku C/C++, która została utworzona za pomocą NDK. Ten przykład znajduje się w katalogu hello-jni w repozytorium ndk-samples w sekcji android-mk branch.

Android.mk

Te 2 wiersze podają nazwę natywnego pliku źródłowego oraz nazwę współdzielonej biblioteki, którą należy skompilować. Pełna nazwa skompilowanej biblioteki to libhello-jni.so, gdy system kompilacji doda prefiks lib i rozszerzenie .so.

LOCAL_SRC_FILES := hello-jni.c
LOCAL_MODULE    := hello-jni

Więcej informacji o tym, do czego służy plik Android.mk, i o sposobach jego używania znajdziesz w pliku Android.mk.

Aplikacja.mk

Ten wiersz informuje system kompilacji o procesorze i architekturze, dla których ma zostać przeprowadzona kompilacja. W tym przykładzie system kompilacji kompiluje dla wszystkich obsługiwanych architektur.

APP_ABI := all

Więcej informacji o pliku Application.mk i sposobie jego używania znajdziesz w pliku Application.mk.

Implementacja po stronie Javy

Plik helloJNI.java znajduje się w folderze hellojni/src/com/example/hellojni/. Wywołuje funkcję, aby pobrać ciąg znaków z wersji natywnej, a potem wyświetla go na ekranie.

Kod źródłowy zawiera trzy wiersze, które szczególnie interesują użytkownika NDK. Są one prezentowane tutaj w takiej kolejności, w jakiej są używane, a nie według kolejności wierszy.

Ten wywołanie funkcji wczytuje plik .so po uruchomieniu aplikacji.

Kotlin

System.loadLibrary("hello-jni")

Java

System.loadLibrary("hello-jni");

Słowo kluczowe native w tej deklaracji metody informuje maszynę wirtualną, że funkcja znajduje się w zasobach wspólnych (czyli jest zaimplementowana po stronie natywnej).

Kotlin

external fun stringFromJNI(): String

Java

public native String stringFromJNI();

Platforma Android wywołuje funkcję załadowaną i deklarowaną w poprzednich krokach, wyświetlając ciąg znaków na ekranie.

Kotlin

tv.text = stringFromJNI()

Java

tv.setText( stringFromJNI() );

Implementacja po stronie C

Plik hello-jni.c znajduje się w folderze hello-jni/jni/. Zawiera on funkcję, która zwraca ciąg znaków, którego żąda strona Java. Deklaracja funkcji wygląda tak:

JNIEXPORT jstring JNICALL
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )

Ta deklaracja odpowiada funkcji natywnej zadeklarowanej w kodzie źródłowym Javy. Zwracany typ jstring to typ danych zdefiniowany w specyfikacji interfejsu natywnego języka Java. W rzeczywistości nie jest to ciąg znaków, tylko wskaźnik do ciągu znaków w języku Java.

Po jstring następuje nazwa funkcji, która jest określana na podstawie nazwy funkcji Java i ścieżki do pliku, który ją zawiera. Utwórz go zgodnie z tymi zasadami:

  • Dodaj do niego Java_.
  • Opisz ścieżkę do pliku w powiązaniu z katalogiem źródłowym najwyższego poziomu.
  • Zamiast ukośników używaj podkreślenia.
  • Pomiń rozszerzenie pliku .java.
  • Po ostatnim podkreśleniu dodaj nazwę funkcji.

Zgodnie z tymi zasadami w tym przykładzie użyto nazwy funkcji Java_com_example_hellojni_HelloJni_stringFromJNI. Nazwa ta odnosi się do funkcji Java o nazwie stringFromJNI(), która znajduje się w pliku hellojni/src/com/example/hellojni/HelloJni.java.

JNIEnv* to wskaźnik do maszyny wirtualnej, a jobject to wskaźnik do obiektu this przekazywanego z poziomu Javy.

Ten wiersz wywołuje interfejs VM API (*env) i przekazuje mu wartość zwracaną, czyli ciąg znaków, którego zażądała funkcja po stronie Java.

return (*env)->NewStringUTF(env, "Hello from JNI !
Compiled with ABI " ABI ".");