הפצת תווכה שפותחה באמצעות ה-NDK מובילה לבעיות נוספות מפתחי האפליקציות לא צריכים לדאוג. ספריות שנוצרו מראש מטילות חלק על המשתמשים שלהם להטמיע מודעות.
בחירת רמות API וגרסאות NDK
המשתמשים לא יכולים להשתמש ב-minSdkVersion שנמוכה משלכם. אם המשתמשים צריכים לרוץ ב-API 21, לא ניתן ליצור עבור API 24. זה בסדר לבנות ברמת ממשק API נמוכה יותר מאשר המשתמשים. אפשר ליצור גרסת API ל-API 16 וימשיכו להיות תואמים למשתמשי API 21 שלכם.
גרסאות NDK בדרך כלל תואמות זו לזו, אבל לפעמים יש שינויים שפוגעים את התאימות. אם אתם יודעים שכל המשתמשים שלכם משתמשים באותה גרסה של ה-NDK, מומלץ להשתמש באותה גרסה שבה הם משתמשים. אחרת, צריך להשתמש בגרסה החדשה ביותר.
שימוש ב-STL
אם אתם כותבים C++ ומשתמשים ב-STL, תוכלו לבחור בין libc++_shared
לבין
אם אתם מפיצים ספרייה משותפת, המדיניות libc++_static
תשפיע על המשתמשים שלכם. אם
להפיץ ספרייה משותפת, עליך להשתמש ב-libc++_shared
או לוודא
הסמלים של libc++ אינם גלויים בספרייה שלך. הדרך הטובה ביותר לעשות זאת היא
להצהיר במפורש על פלטפורמת ה-ABI באמצעות סקריפט גרסה (הפעולה הזו גם עוזרת
(פרטי ההטמעה פרטיים). לדוגמה, ספרייה פשוטה
יכול להיות סקריפט הגרסה הבא:
LIBMYMATH {
global:
add;
sub;
mul;
div;
# C++ symbols in an extern block will be mangled automatically. See
# https://stackoverflow.com/a/21845178/632035 for more examples.
extern "C++" {
"pow(int, int)";
}
local:
*;
};
סקריפט הגרסה צריך להיות האפשרות המועדפת משום שהוא דרך לשלוט בחשיפה של הסמלים. זוהי שיטה מומלצת לכל הנכסים המשותפים תווכה, תווכה או לא, כי היא מונעת מפרטי ההטמעה חשיפה ומשפרת את זמן הטעינה.
אפשרות נוספת ופחות מועילה היא להשתמש ב--Wl,--exclude-libs,libc++_static.a
-Wl,--exclude-libs,libc++abi.a
כשמקשרים. זה פחות מתקדם כי
יסתיר את הסמלים רק בספריות שיש להן שם מפורש, ולא
מתבצע דיווח על ניתוחים של ספריות שלא נעשה בהן שימוש (שגיאת הקלדה בספרייה
אינו שגיאה, והעומס הוא על המשתמש לשמור את רשימת הספרייה
עד היום). השיטה הזו גם לא מסתירה את פרטי ההטמעה שלכם.
הפצת ספריות מקוריות בקובצי AAR
הפלאגין של Android Gradle יכול לייבא יחסי תלות מקוריים שמופצים ב AAR. אם המשתמשים שלך משתמשים בפלאגין של Android Gradle, זו תהיה את הדרך הקלה ביותר בשבילם לצרוך את הספרייה שלכם.
ניתן לארוז ספריות מקוריות לתוך AAR באמצעות AGP. זו תהיה האפשרות הקלה ביותר אם הספרייה כבר נוצרה על ידי externalNativeBuild.
גרסאות build שאינן של AGP יכולות להשתמש ב-ndkport או לבצע אריזה ידנית לפי
מסמכי תיעוד של Prefab כדי ליצור את ספריית המשנה prefab/
של ה-AAR שלהם.
תווכה של Java עם ספריות JNI
ספריות Java שכוללות ספריות JNI (במילים אחרות, קובצי AAR שכוללים
jniLibs
) צריך להיזהר שספריות ה-JNI שהן כוללות לא
יתנגשו עם ספריות אחרות באפליקציה של המשתמש. לדוגמה, אם AAR כולל
libc++_shared.so
, אבל גרסה של libc++_shared.so
שונה מזו של האפליקציה
רק אחד מהם יותקן ל-APK, דבר שעלול להוביל לחוסר אמינות
או התנהגות המשתמשים.
הפתרון האמין ביותר הוא שספריות Java לא יכללו יותר מאחת.
ספריית JNI (זו המלצה טובה גם לאפליקציות). כל יחסי התלות, כולל
צריך לקשר את STL באופן סטטי לספריית ההטמעה, וגרסה
צריך להשתמש בסקריפט כדי לאכוף את פלטפורמת ה-ABI. לדוגמה, ספריית Java
com.example.foo
שכולל את ספריית ה-JNI libfooimpl.so
צריך להשתמש ב-
סקריפט הגרסה הבאה:
LIBFOOIMPL {
global:
JNI_OnLoad;
local:
*;
};
הדוגמה הזו משתמשת ב-registerNatives
דרך JNI_OnLoad
כפי שמתואר בטיפים של JNI
כדי להבטיח ששטח ה-ABI המינימלי חשוף ושזמן הטעינה של הספרייה
הן מינימליות.