באפליקציות ל-Android אפשר להגדיר מספר מאפיינים של גרסת ה-SDK בקובץ build.gradle
. בתיעוד של Android build.gradle
מוסבר מה המשמעות של המאפיינים האלה לגבי האפליקציה באופן כללי. במאמר הזה נסביר איך המאפיינים האלה משפיעים על בניית NDK.
compileSdkVersion
למאפיין הזה אין השפעה על בניית NDK. הזמינות של ה-API עבור NDK נקבעת על ידי minSdkVersion
. הסיבה לכך היא שסמלי C++ נפתרים באופן מיידי בזמן טעינת הספרייה, ולא באופן הדרגתי כשקוראים להם בפעם הראשונה (כמו ב-Java). שימוש בסמלים שלא זמינים ב-minSdkVersion
יגרום לטעינת הספרייה להיכשל בגרסאות של מערכת ההפעלה שאין בהן את ה-API החדש יותר, בלי קשר לשאלה אם ממשקי ה-API האלה יופעלו או לא.
אם מדובר באפליקציה חדשה, בוחרים את הגרסה העדכנית ביותר שזמינה. אם מדובר באפליקציה קיימת, כדאי לעדכן אותה לגרסה העדכנית כשנוח.
targetSdkVersion
בדומה ל-Java, targetSdkVersion
של האפליקציה יכול לשנות את התנהגות זמן הריצה של קוד מקומי. שינויים בהתנהגות המערכת, ככל האפשר, חלים רק על אפליקציות עם targetSdkVersion
שגדול או שווה לגרסת מערכת ההפעלה שבה הוצג השינוי.
אם מדובר באפליקציה חדשה, בוחרים את הגרסה העדכנית ביותר שזמינה. אם יש לכם אפליקציה קיימת, כדאי לעדכן אותה לגרסה העדכנית כשנוח לכם (אחרי עדכון compileSdkVersion
).
מפתחי אפליקציות בדרך כלל יודעים מהו targetSdkVersion
של האפליקציה שלהם, אבל ה-API הזה שימושי למפתחי ספריות שלא יכולים לדעת איזה targetSdkVersion
המשתמשים שלהם יבחרו.
בזמן הריצה, אפשר לקבל את targetSdkVersion
שבו נעשה שימוש באפליקציה על ידי קריאה ל-android_get_application_target_sdk_version()
. ה-API הזה זמין ברמה 24 ומעלה. החתימה של הפונקציה הזו היא:
/**
* Returns the `targetSdkVersion` of the caller, or `__ANDROID_API_FUTURE__` if
* there is no known target SDK version (for code not running in the context of
* an app).
*
* The returned values correspond to the named constants in `<android/api-level.h>`,
* and is equivalent to the AndroidManifest.xml `targetSdkVersion`.
*
* See also android_get_device_api_level().
*
* Available since API level 24.
*/
int android_get_application_target_sdk_version() __INTRODUCED_IN(24);
שינויים אחרים בהתנהגות עשויים להיות תלויים ברמת ה-API של המכשיר. אפשר לקבל את רמת ה-API של המכשיר שבו האפליקציה פועלת באמצעות קריאה ל-android_get_device_api_level()
. החתימה של הפונקציה הזו היא:
/**
* Returns the API level of the device we're actually running on, or -1 on failure.
* The returned values correspond to the named constants in `<android/api-level.h>`,
* and is equivalent to the Java `Build.VERSION.SDK_INT` API.
*
* See also android_get_application_target_sdk_version().
*/
int android_get_device_api_level();
קבלת רמות API של המכשיר מאפשרת לקוד NDK לזהות באופן דינמי שינויים בהתנהגות בפלטפורמה. מכיוון שרמות API משניות לא קשורות לשינויים בהתנהגות, ואין לנו תוכניות להוסיף פונקציונליות חדשה של NDK ברמות API משניות, אין דרך לקבל את רמת ה-API המלאה של המכשיר ישירות מקריאה ל-NDK.
אתם יכולים להשתמש ב-dlopen()
/dlsym()
או בהפניות API חלשות כדי לקרוא לממשקי API חדשים יותר מאלה שצוינו ב-minSdkVersion
.
maxSdkVersion
למאפיין הזה אין השפעה על בניית NDK.
minSdkVersion
הערך minSdkVersion
שמוגדר בקובץ build.gradle
קובע אילו ממשקי API זמינים בזמן הבנייה (כדאי לעיין במאמר בנושא compileSdkVersion כדי להבין למה זה שונה מבנייה של Java), וקובע את הגרסה המינימלית של מערכת ההפעלה שהקוד שלכם יהיה תואם לה.
minSdkVersion
משמש את NDK כדי לקבוע באילו תכונות אפשר להשתמש כשמבצעים קומפילציה של הקוד. לדוגמה, המאפיין הזה קובע באילו תכונות של FORTIFY נעשה שימוש ב-libc, ויכול גם לשפר את הביצועים או את הגודל (למשל גיבוב GNU או RELR) בקבצים הבינאריים שלא תואמים לגרסאות ישנות יותר של Android. גם אם לא משתמשים בממשקי API חדשים, המאפיין הזה עדיין קובע את גרסת מערכת ההפעלה המינימלית שנתמכת בקוד.
באפליקציה חדשה, אפשר לראות את נתוני חלוקת המשתמשים באשף New Project (פרויקט חדש) של Android Studio או באתר apilevels.com. כדאי לבחור את האיזון בין פוטנציאל נתח השוק לבין עלויות התחזוקה. ככל שערך minSdkVersion
נמוך יותר, כך תצטרכו להשקיע יותר זמן בפתרון באגים ישנים ובהוספת התנהגויות חלופיות לתכונות שעדיין לא יושמו.
באפליקציה קיימת, צריך להעלות את minSdkVersion
אם רמות API ישנות כבר לא מצדיקות את עלויות התחזוקה, או להוריד אותה אם המשתמשים דורשים זאת והעלויות החדשות של התחזוקה מצדיקות את זה. ב-Play Console יש מדדים שספציפיים להפצה של המשתמשים באפליקציה שלכם.
הערך minSdkVersion
של האפליקציה זמין למעבד המקדים באמצעות מאקרו __ANDROID_MIN_SDK_VERSION__
(המאקרו הקודם __ANDROID_API__
זהה, אבל עדיף להשתמש במאקרו הראשון כי המשמעות שלו ברורה יותר). המאקרו הזה מוגדר אוטומטית על ידי Clang, כך שלא צריך לכלול קובץ כותרת כדי להשתמש בו. ב-NDK builds, המאקרו הזה תמיד מוגדר.