החל מ-Android 9 (רמת API 28), הפלטפורמה מגבילה את הממשקים שאינם SDK שהאפליקציה יכולה להשתמש בהם. ההגבלות האלה חלות בכל פעם שאפליקציה מפנה לממשק שאינו SDK או מנסה לקבל את נקודת האחיזה שלו באמצעות השתקפות או JNI. ההגבלות האלה נועדו לשפר את חוויית המשתמשים והמפתחים, לצמצם את הסיכון לקריסות אצל המשתמשים ולהפחית את הצורך של המפתחים להשיק גרסאות חירום. למידע נוסף על ההחלטה הזו, קראו את המאמר Improving Stability by Reducing Usage of non-SDK Interfaces.
הבחנה בין ממשקי SDK לממשקים שאינם SDK
באופן כללי, ממשקי SDK ציבוריים הם אלה שמתועדים באינדקס החבילות של Android framework. הטיפול בממשקים שאינם SDK הוא פרט הטמעה שמופשט על ידי ה-API, ולכן הממשקים האלה כפופים לשינויים ללא הודעה מוקדמת.
כדי למנוע קריסות והתנהגות לא צפויה, האפליקציות צריכות להשתמש רק בחלקים המתועדים באופן רשמי של המחלקות ב-SDK. זה גם אומר שאתם לא צריכים לגשת לשיטות או לשדות שלא מופיעים ב-SDK כשאתם יוצרים אינטראקציה עם מחלקה באמצעות מנגנונים כמו השתקפות.
רשימות של ממשקי API שאינם SDK
בכל גרסה של Android, אנחנו מגבילים ממשקים נוספים שאינם SDK. אנחנו יודעים שההגבלות האלה יכולות להשפיע על תהליך העבודה שלכם, ואנחנו רוצים לוודא שיש לכם את הכלים לזהות שימוש בממשקים שאינם SDK, הזדמנות לתת לנו משוב וזמן לתכנן ולהתאים את עצמכם למדיניות החדשה.
כדי לצמצם את ההשפעה של ההגבלות על ממשקים שאינם חלק מ-SDK על תהליך הפיתוח, הממשקים האלה מחולקים לרשימות שמגדירות את רמת ההגבלה על השימוש בהם, בהתאם לרמת ה-API שאליה הם מטרגטים. בטבלה הבאה מתוארת כל אחת מהרשימות האלה:
| רשימה | תגי קוד | תיאור |
|---|---|---|
| רשימת חסימה |
|
ממשקים שאינם SDK שאי אפשר להשתמש בהם, בלי קשר לרמת ה-API המיועדת של האפליקציה. אם האפליקציה מנסה לגשת לאחד מהממשקים האלה, המערכת מקפיצה שגיאה. |
| חסימה מותנית |
|
החל מ-Android 9 (רמת API 28), לכל רמת API יש ממשקים שאינם SDK שמוגבלים כשאפליקציה מטרגטת את רמת ה-API הזו. הרשימות האלה מסומנות לפי רמת ה-API המקסימלית ( אם האפליקציה מנסה לגשת לממשק שמוגבל ברמת ה-API המיועדת, המערכת מתנהגת כאילו ה-API הוא חלק מרשימת החסימה. |
| לא נתמך |
|
ממשקים שאינם SDK, שאין להם הגבלות ושהאפליקציה יכולה להשתמש בהם. עם זאת, חשוב לזכור שהממשקים האלה לא נתמכים ויכולים להשתנות ללא הודעה מוקדמת. בגרסאות עתידיות של Android, הממשקים האלה ייחסמו באופן מותנה ברשימה max-target-x. |
| SDK |
|
ממשקים שאפשר להשתמש בהם באופן חופשי, ונתמכים עכשיו כחלק מאינדקס החבילות של Android framework שמתועד באופן רשמי. |
| ממשקי API לבדיקה |
|
ממשקים שמשמשים לבדיקת מערכת פנימית, כמו ממשקי API שמאפשרים בדיקה באמצעות חבילה לבדיקות תאימות (CTS). ממשקי API לבדיקה הם לא חלק מה-SDK. החל מ-Android 11 (רמת API 30), ממשקי API לבדיקה נכללים ברשימת החסימה, ולכן לאפליקציות אסור להשתמש בהם, בלי קשר לרמת ה-API המטורגטת שלהן. כל ממשקי ה-API לבדיקה לא נתמכים ויכולים להשתנות בלי הודעה מוקדמת, בלי קשר לרמת ה-API של הפלטפורמה. |
אפשר להשתמש בממשקים מסוימים שאינם SDK (בהתאם לרמת ה-API המיועדת של האפליקציה), אבל שימוש בכל שיטה או שדה שאינם SDK תמיד כרוך בסיכון גבוה לפגיעה באפליקציה. אם האפליקציה שלכם מסתמכת על ממשקים שאינם SDK, כדאי להתחיל לתכנן מעבר לממשקי SDK או לחלופות אחרות. אם אתם לא מוצאים חלופה לשימוש בממשק שאינו SDK לתכונה באפליקציה, אתם צריכים לבקש API ציבורי חדש.
איך בודקים לאיזו רשימה שייך ממשק מסוים
הרשימות של ממשקים שאינם SDK נוצרות כחלק מהפלטפורמה. בקטעים הבאים מפורט מידע על כל גרסה של Android.
Android 16
ב-Android 16 (רמת API 36), אתם יכולים להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות המתאימות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
9102af02fe6ab68b92464bdff5e5b09f3bd62c65d1130aaf85d3296f17d38074
מידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 16 זמין במאמר עדכונים להגבלות על ממשקים שאינם SDK ב-Android 16.
Android 15
ב-Android 15 (רמת API 35), אתם יכולים להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות המתאימות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
40134e205e58922a708c453726b279a296e6a1f34a988abd90cec0f3432ea5a9
מידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 15 זמין במאמר עדכונים להגבלות על ממשקים שאינם SDK ב-Android 15.
Android 14
ב-Android 14 (רמת API 34), אתם יכולים להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות התואמות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f
מידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 14 זמין במאמר עדכונים להגבלות על ממשקים שאינם SDK ב-Android 14.
Android 13
ב-Android 13 (רמת API 33), אפשר להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות המתאימות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3
כדי לקבל מידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 13, כולל הצעות לממשקי API ציבוריים חלופיים לממשקי API שנחסמים באופן מותנה ב-Android 13, אפשר לעיין במאמר עדכונים להגבלות על ממשקים שאינם SDK ב-Android 13.
12 Android
ב-Android 12 (רמת API 31), אתם יכולים להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות התואמות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761
למידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 12, כולל הצעות לחלופות של ממשקי API ציבוריים לממשקי API שנחסמים באופן מותנה ב-Android 12, ראו שינויים ברשימה עבור Android 12.
Android 11
ב-Android 11 (רמת API 30), אפשר להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות התואמות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56
למידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 11, כולל הצעות לחלופות של ממשקי API ציבוריים לממשקי API שנחסמו באופן מותנה ב-Android 11, ראו שינויים ברשימה עבור Android 11.
Android 10
ב-Android 10 (רמת API 29), אפשר להוריד את הקובץ הבא שמתאר את כל הממשקים שאינם SDK ואת הרשימות התואמות שלהם:
קובץ: hiddenapi-flags.csv
סיכום ביקורת (checksum) של SHA-256:
f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb
למידע נוסף על השינויים ברשימת ממשקי ה-API שאינם SDK ב-Android 10, כולל הצעות לחלופות של ממשקי API ציבוריים לממשקי API שנחסמים באופן מותנה ב-Android 10, ראו שינויים ברשימה עבור Android 10.
Android 9
ב-Android 9 (רמת API 28), קובץ הטקסט הבא מכיל את רשימת ממשקי ה-API שאינם SDK, שאינם מוגבלים (רשימה אפורה): hiddenapi-light-greylist.txt.
רשימת החסימה (blacklist) והרשימה של ממשקי ה-API שחסומים באופן מותנה (רשימה אפורה כהה) נגזרות בזמן ה-build.
יצירת רשימות מ-AOSP
כשעובדים עם AOSP, אפשר ליצור קובץ hiddenapi-flags.csv שמכיל את כל הממשקים שאינם SDK ואת הרשימות התואמות שלהם. כדי לעשות את זה, מורידים את קוד המקור של AOSP ואז מריצים את הפקודה הבאה:
m out/soong/hiddenapi/hiddenapi-flags.csv
אחרי זה, אפשר למצוא את הקובץ במיקום הבא:
out/soong/hiddenapi/hiddenapi-flags.csv
ההתנהגות הצפויה כשניגשים לממשקים מוגבלים שאינם SDK
בטבלה הבאה מתוארת ההתנהגות הצפויה אם האפליקציה מנסה לגשת לממשק שאינו SDK שנמצא ברשימת החסימה.
| אמצעי גישה | תוצאה |
|---|---|
| הוראת Dalvik שמפנה לשדה | נזרקה שגיאה מסוג NoSuchFieldError |
| הוראת Dalvik שמפנה ל-method | נזרק NoSuchMethodError |
השתקפות באמצעות Class.getDeclaredField() או Class.getField() |
נזרקה שגיאה מסוג NoSuchFieldException |
השתקפות באמצעות Class.getDeclaredMethod(), Class.getMethod() |
נזרק NoSuchMethodException |
השתקפות באמצעות Class.getDeclaredFields(), Class.getFields() |
חברים שלא משתמשים ב-SDK לא מופיעים בתוצאות |
השתקפות באמצעות Class.getDeclaredMethods(), Class.getMethods() |
חברים שלא משתמשים ב-SDK לא מופיעים בתוצאות |
JNI באמצעות env->GetFieldID() |
הוחזר: NULL, נזרק: NoSuchFieldError |
JNI באמצעות env->GetMethodID() |
הוחזר: NULL, נזרק: NoSuchMethodError |
בדיקת האפליקציה לאיתור ממשקים שאינם SDK
יש כמה שיטות שבהן אפשר להשתמש כדי לבדוק אם יש באפליקציה ממשקים שאינם SDK.
בדיקה באמצעות אפליקציה שניתן לנפות בה באגים
כדי לבדוק אם יש ממשקים שלא שייכים ל-SDK, אתם יכולים ליצור ולהפעיל אפליקציה שניתן לבצע בה ניפוי באגים במכשיר או באמולטור עם Android 9 (רמת API 28) ומעלה. חשוב לוודא שהמכשיר או האמולטור שאתם משתמשים בו תואם לרמת ה-API המיועדת של האפליקציה.
בזמן הרצת הבדיקות באפליקציה, המערכת מדפיסה הודעת יומן אם האפליקציה ניגשת לממשקים מסוימים שאינם SDK. אתם יכולים לבדוק את הודעות היומן של האפליקציה כדי למצוא את הפרטים הבאים:
- המחלקה המצהירה, השם והסוג (בפורמט שבו משתמשת סביבת זמן הריצה ל-Android).
- אמצעי הגישה: קישור, שימוש ב-reflection או שימוש ב-JNI.
- הרשימה שאליה שייך הממשק שאינו SDK.
אפשר להשתמש ב-adb logcat כדי לגשת להודעות האלה ביומן, שמופיעות מתחת למזהה התהליך (PID) של האפליקציה שפועלת. לדוגמה, רשומה ביומן יכולה להיראות כך:
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
בדיקה באמצעות StrictMode API
אפשר גם לבדוק ממשקים שאינם SDK באמצעות ה-API של StrictMode. כדי להפעיל את האפשרות הזו, משתמשים ב-method detectNonSdkApiUsage. אחרי שמפעילים את ה-API של StrictMode, אפשר לקבל קריאה חוזרת (callback) לכל שימוש בממשק שאינו SDK באמצעות penaltyListener, שבו אפשר להטמיע טיפול בהתאמה אישית. האובייקט Violation שסופק בקריאה החוזרת (callback) נגזר מ-Throwable, ודוח הקריסות המצורף מספק את ההקשר של השימוש.
בדיקה באמצעות הכלי לניתוח קוד סטטי (lint) ב-Android Studio
בכל פעם שאתם יוצרים את האפליקציה ב-Android Studio, הכלי לניתוח קוד סטטי בודק את הקוד כדי לאתר בעיות פוטנציאליות. אם האפליקציה שלכם משתמשת בממשקים שאינם SDK, יכול להיות שיופיעו שגיאות או אזהרות ב-build, בהתאם לרשימה שאליה הממשקים האלה שייכים.
אפשר גם להריץ את כלי ה-lint משורת הפקודה או להריץ בדיקות באופן ידני בפרויקט, בתיקייה או בקובץ ספציפיים.
בדיקה באמצעות Play Console
כשמעלים את האפליקציה למסלול בדיקה ב-Play Console, היא נבדקת באופן אוטומטי כדי לאתר בעיות פוטנציאליות ונוצר דוח טרום-השקה. אם האפליקציה משתמשת בממשקים שאינם של SDK, תוצג שגיאה או אזהרה בדוח טרום-השקה, בהתאם לרשימה שאליה הממשקים האלה שייכים.
מידע נוסף זמין בקטע "תאימות ל-Android" במאמר שימוש בדוחות טרום-השקה כדי לזהות בעיות.
בקשה ליצירת API ציבורי חדש
אם אתם לא מוצאים חלופה לשימוש בממשק שאינו SDK לתכונה באפליקציה, אתם יכולים לבקש API ציבורי חדש על ידי הגשת בקשה להוספת תכונה ב-Issue Tracker.
כשמגישים בקשה להוספת תכונה, צריך לספק את הפרטים הבאים:
- באיזה API לא נתמך אתם משתמשים, כולל התיאור המלא שמופיע בהודעת ה-logcat של
Accessing hidden .... - למה אתם צריכים להשתמש בממשקי ה-API האלה, כולל פרטים על התכונה ברמה הגבוהה שה-API נדרש בשבילה, ולא רק פרטים ברמה הנמוכה.
- למה ממשקי API ציבוריים קשורים של SDK לא מספיקים למטרות שלכם.
- חלופות אחרות שניסיתם ולמה הן לא עבדו.
כשאתם מספקים את הפרטים האלה בבקשה להוספת תכונה, אתם מגדילים את הסיכוי ש-API ציבורי חדש יאושר.
שאלות נוספות
בקטע הזה ריכזנו תשובות לשאלות נפוצות נוספות של מפתחים:
שאלות כלליות
איך Google יכולה להיות בטוחה שהיא יכולה לתעד את הצרכים של כל האפליקציות באמצעות הכלי למעקב אחר בעיות?
יצרנו את הרשימות הראשוניות ל-Android 9 (רמת API 28) באמצעות ניתוח סטטי של אפליקציות, שהושלם באמצעות השיטות הבאות:
- בדיקה ידנית של האפליקציות המובילות ב-Play ומחוץ ל-Play
- דוחות פנימיים
- איסוף נתונים אוטומטי ממשתמשים פנימיים
- דוחות של תצוגה מקדימה למפתחים
- ניתוח סטטי נוסף שנועד לכלול באופן שמרני יותר תוצאות חיוביות מוטעות
כשאנחנו בודקים את הרשימות לכל גרסה חדשה, אנחנו מביאים בחשבון את השימוש ב-API וגם את המשוב מהמפתחים דרך ה-Issue Tracker.
איך אפשר להפעיל גישה לממשקים שאינם SDK?
כדי לאפשר גישה לממשקים שאינם SDK במכשירי פיתוח, אפשר להשתמש בפקודות adb כדי לשנות את מדיניות האכיפה של ה-API. הפקודות שבהן משתמשים משתנות בהתאם לרמת ה-API. הפקודות האלה לא דורשות מכשיר עם הרשאות בסיס.
- Android מגרסה 10 (רמת API 29) ואילך
כדי לאפשר גישה, משתמשים בפקודת ה-adb הבאה:
פקודה:
adb shell settings put global hidden_api_policy 1
כדי לאפס את מדיניות האכיפה של ה-API להגדרות ברירת המחדל, משתמשים בפקודה הבאה:
adb shell settings delete global hidden_api_policy
- Android 9 (רמת API 28)
כדי לאפשר גישה, משתמשים בפקודות ה-adb הבאות:
adb shell settings put global hidden_api_policy_pre_p_apps 1adb shell settings put global hidden_api_policy_p_apps 1כדי לאפס את מדיניות האכיפה של ה-API להגדרות ברירת המחדל, משתמשים בפקודות הבאות:
adb shell settings delete global hidden_api_policy_pre_p_appsadb shell settings delete global hidden_api_policy_p_apps
אפשר להגדיר את המספר השלם במדיניות האכיפה של ה-API לאחד מהערכים הבאים:
- 0: השבתת כל הזיהוי של ממשקים שאינם SDK. ההגדרה הזו משביתה את כל הודעות היומן לגבי שימוש בממשקים שאינם SDK, ומונעת מכם לבדוק את האפליקציה באמצעות ה-API של
StrictMode. לא מומלץ להשתמש בהגדרה הזו. - 1: הפעלת הגישה לכל הממשקים שאינם SDK, אבל הדפסת הודעות ביומן עם אזהרות לגבי כל שימוש בממשק שאינו SDK. ההגדרה הזו גם מאפשרת לבדוק את האפליקציה באמצעות
StrictModeAPI. - 2: לא לאפשר שימוש בממשקים שאינם SDK ששייכים לרשימת החסימה או שנחסמו באופן מותנה ברמת ה-API המיועדת.
שאלות על רשימות של ממשקים שאינם חלק מ-SDK
איפה אפשר למצוא את רשימות ה-API שאינן SDK בתמונת המערכת?
הם מקודדים בביטים של דגלי הגישה לשדות ולשיטות בקובצי dex של הפלטפורמה. אין קובץ נפרד בתמונת המערכת שמכיל את הרשימות האלה.
האם רשימות ה-API שאינן SDK זהות במכשירים של יצרני ציוד מקורי (OEM) שונים עם אותן גרסאות Android?
יצרני ציוד מקורי (OEM) יכולים להוסיף ממשקים משלהם לרשימת החסימה (רשימה שחורה), אבל הם לא יכולים להסיר ממשקים מרשימות ה-API שאינן SDK של AOSP. מסמך הגדרת התאימות (CDD) מונע שינויים כאלה, ובדיקות CTS מוודאות שסביבת זמן הריצה ל-Android (ART) אוכפת את הרשימה.
שאלות לגבי התאימות של אפליקציות קשורות
האם יש הגבלה על ממשקים שאינם NDK בקוד Native?
Android SDK כולל ממשקי Java. הפלטפורמה התחילה להגביל את הגישה לממשקים שאינם NDK לקוד C/C++ מקורי ב-Android 7 (רמת API 26). מידע נוסף זמין במאמר Improving Stability with Private C/C++ Symbol Restrictions in Android N.
האם יש תוכנית להגביל את dex2oat או את השינוי של קובצי DEX?
אין לנו תוכניות פעילות להגביל את הגישה לקובץ הבינארי dex2oat, אבל אנחנו לא מתכוונים שפורמט הקובץ DEX יהיה יציב או ממשק ציבורי מעבר לחלקים שצוינו באופן ציבורי בפורמט Dalvik Executable. אנחנו שומרים לעצמנו את הזכות לשנות או להסיר את dex2oat ואת החלקים הלא מוגדרים של פורמט DEX בכל שלב. חשוב גם לציין שקבצים נגזרים שנוצרו על ידי dex2oat, כמו ODEX (שנקרא גם OAT), VDEX ו-CDEX, הם כולם פורמטים לא מוגדרים.
מה קורה אם ערכת SDK חיונית של צד שלישי (לדוגמה, ערכה לערפול קוד) לא יכולה להימנע משימוש בממשקים שאינם של SDK, אבל מתחייבת לשמור על תאימות עם גרסאות עתידיות של Android? האם Android יכולה לוותר על דרישות התאימות שלה במקרה הזה?
אין לנו תוכניות לוותר על דרישות התאימות לכל ערכת SDK בנפרד. אם מפתחי SDK יכולים לשמור על תאימות רק על ידי הסתמכות על ממשקים ברשימות הלא נתמכות (לשעבר אפורות), הם צריכים להתחיל לתכנן מעבר לממשקי SDK או לחלופות אחרות, ולבקש API ציבורי חדש בכל פעם שהם לא יכולים למצוא חלופה לשימוש בממשק שאינו SDK.
האם ההגבלות על ממשקים שאינם SDK חלות על כל האפליקציות, כולל אפליקציות מערכת ואפליקציות מבית Google, ולא רק על אפליקציות של צד שלישי?
כן, אבל אנחנו מחריגים אפליקציות שנחתמו באמצעות מפתח הפלטפורמה ואפליקציות מסוימות של קובץ אימג' של המערכת. חשוב לזכור שהפטורים האלה חלים רק על אפליקציות שהן חלק מתמונת המערכת (או אפליקציות מעודכנות של תמונת המערכת). הרשימה מיועדת רק לאפליקציות שנוצרו באמצעות ממשקי ה-API של הפלטפורמה הפרטית, ולא באמצעות ממשקי ה-API של ה-SDK (כאשר LOCAL_PRIVATE_PLATFORM_APIS := true).