這個範例會引導您使用 NDK 建構小型 C/C++ 應用程式 hello-jni。您可以在 android-mk 分支版本中 ndk-samples 存放區的 hello-jni 目錄找到這個範例。
Android.mk
以下兩行程式碼提供原生來源檔案的名稱,以及要建構的共用程式庫名稱。建構系統新增 lib
前置字串和 .so
副檔名之後,建構程式庫的全名會是 libhello-jni.so
。
LOCAL_SRC_FILES := hello-jni.c LOCAL_MODULE := hello-jni
如要進一步瞭解 Android.mk
檔案的用途和使用方法,請參閱 Android.mk。
Application.mk
這行程式碼會指示建構系統要針對哪個 CPU 和架構進行建構。在這個範例中,建構系統會針對所有支援的架構進行建構。
APP_ABI := all
如要進一步瞭解 Application.mk
檔案及其使用方法,請參閱 Application.mk。
Java 端實作
helloJNI.java
檔案位於 hellojni/src/com/example/hellojni/
中。這個檔案會呼叫函式從原生端擷取字串,然後在螢幕上顯示該字串。
原始碼包含 NDK 使用者應特別留意的三行程式碼。 下文將以使用順序 (而非編寫的順序) 展示這三行程式碼。
應用程式啟動時,這項函式呼叫便會載入 .so
檔案。
Kotlin
System.loadLibrary("hello-jni")
Java
System.loadLibrary("hello-jni");
在這個方法宣告中,native
關鍵字的作用是告知虛擬機器函式位於共用程式庫中 (亦即已在原生端實作)。
Kotlin
external fun stringFromJNI(): String
Java
public native String stringFromJNI();
Android 架構會呼叫上述步驟中載入及宣告的函式,並在螢幕上顯示字串。
Kotlin
tv.text = stringFromJNI()
Java
tv.setText( stringFromJNI() );
C 端實作
hello-jni.c
檔案位於 hello-jni/jni/
中,其中包含的函式會傳回 Java 端要求的字串。函式宣告如下:
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
這個宣告與 Java 原始碼中宣告的原生函式對應。傳回類型 jstring
是 Java 原生介面規範中定義的資料類型,它是 Java 字串的指標,並非真正的字串。
傳回 jstring
後,接著是根據 Java 函式名稱和這個函式所在檔案的路徑傳回的函式名稱。請根據下列規則設定函式名稱:
- 在開頭加上
Java_
。 - 說明與頂層來源目錄相關的檔案路徑。
- 以底線取代正斜線。
- 刪除
.java
副檔名。 - 在最後一個底線後面加上函式名稱。
依據這些規則,這個範例使用的函式名稱是 Java_com_example_hellojni_HelloJni_stringFromJNI
。這個名稱指的是 hellojni/src/com/example/hellojni/HelloJni.java
中一個名為 stringFromJNI()
的 Java 函式。
JNIEnv*
是 VM 的指標,而 jobject
是從 Java 端傳遞的隱含 this
物件的指標。
以下這行程式碼會呼叫 VM API (*env)
,並向其傳遞傳回值 (亦即 Java 端函式要求的字串)。
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");