בדוגמה הזו נסביר על hello-jni, אפליקציה מינימלית ב-C/C++ שנוצרה באמצעות NDK. הדוגמה הזו נמצאת בתיקייה hello-jni במאגר ndk-samples, בתוך ההסתעפות android-mk.
Android.mk
בשתי השורות הבאות מופיע שם קובץ המקור המקורי, יחד עם שם הספרייה המשותפת ליצירה. השם המלא של הספרייה שנוצרה הוא libhello-jni.so
, אחרי שמערכת ה-build מוסיפה את הקידומת lib
והסיומת .so
.
LOCAL_SRC_FILES := hello-jni.c LOCAL_MODULE := hello-jni
למידע נוסף על הפונקציות של הקובץ Android.mk
ועל אופן השימוש בו, קראו את המאמר Android.mk.
Application.mk
השורה הזו מנחה את מערכת ה-build לגבי המעבד (CPU) והארכיטקטורה שמהם יש לבנות. בדוגמה הזו, מערכת ה-build יוצרת גרסאות לכל הארכיטקטורות הנתמכות.
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 Native. זהו לא מחרוזת, אלא פוינטר למחרוזת Java.
אחרי jstring
מופיע שם הפונקציה, שמבוסס על שם הפונקציה ב-Java ועל הנתיב לקובץ שמכיל אותה. יוצרים אותו לפי הכללים הבאים:
- מוסיפים את
Java_
בתחילת השם. - תיאור נתיב הקובץ ביחס לספריית המקור ברמה העליונה.
- משתמשים בקו תחתון במקום בקו נטוי קדימה.
- השמטת את סיומת הקובץ
.java
. - אחרי הקו התחתון האחרון, מוסיפים את שם הפונקציה.
בהתאם לכללים האלו, הדוגמה הזו משתמשת בשם הפונקציה Java_com_example_hellojni_HelloJni_stringFromJNI
. השם הזה מתייחס לפונקציית Java stringFromJNI()
שנמצאת ב-hellojni/src/com/example/hellojni/HelloJni.java
.
JNIEnv*
הוא הפונקציה שמצביעה על המכונה הווירטואלית, ו-jobject
הוא הפונקציה שמצביעה על אובייקט this
המשתמעים שהועברו מצד Java.
השורה הבאה קוראת ל-VM API (*env)
ומעבירה לו ערך החזרה: כלומר, המחרוזת שהפונקציה בצד Java ביקשה.
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");