ייעוץ לספקי תווכה

הפצת תווכה שפותחה באמצעות ה-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 המינימלי חשוף ושזמן הטעינה של הספרייה הן מינימליות.