דוגמה: 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 בהצהרת ה-method הזו מציינת את אלה מכונה וירטואלית שהפונקציה נמצאת בספרייה המשותפת (כלומר, מוטמעת בסביבה המקורית ).

Kotlin

external fun stringFromJNI(): String

Java

public native String stringFromJNI();

ה-framework של 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 המונח מתייחס ל-Java בפונקציה stringFromJNI(), שנמצאת hellojni/src/com/example/hellojni/HelloJni.java.

JNIEnv* הוא המצביע ל-VM, jobject הוא מצביע לאובייקט המרומז this שמועבר מ- הצד של Java.

השורה הבאה קוראת ל-VM API (*env) ומעבירה לו ערך מוחזר: כלומר, המחרוזת שהפונקציה בצד Java ביקשה.

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