שינויים בהתנהגות: אפליקציות שמטרגטות את API 29 ואילך

‫Android 10 כולל שינויים מעודכנים בהתנהגות המערכת שעשויים להשפיע על האפליקציה שלכם. השינויים שמפורטים בדף הזה רלוונטיים רק לאפליקציות שמטרגטות את API ברמה 29 ומעלה. אם האפליקציה שלכם מגדירה את targetSdkVersion לערך 29 ומעלה, אתם צריכים לשנות את האפליקציה כדי שהיא תתמוך בהתנהגויות האלה בצורה תקינה, במקרים הרלוונטיים.

חשוב גם לבדוק את רשימת השינויים בהתנהגות שמשפיעים על כל האפליקציות שפועלות ב-Android 10.

הערה: בנוסף לשינויים שמפורטים בדף הזה, ב-Android 10 יש מספר רב של שינויים והגבלות שקשורים לפרטיות, כולל:

  • נפח אחסון ייעודי לאפליקציות
  • גישה למספר הסידורי של מכשיר USB
  • אפשרות להפעיל, להשבית ולהגדיר Wi-Fi
  • הרשאות מיקום לממשקי API של קישוריות

השינויים האלה משפיעים על אפליקציות שמטרגטות לרמת API 29 ומעלה, והם משפרים את פרטיות המשתמשים. מידע נוסף על השינויים האלה זמין בדף שינויים בפרטיות.

עדכונים בהגבלות על ממשקים שאינם ב-SDK

כדי לשפר את היציבות והתאימות של האפליקציות, הפלטפורמה התחילה להגביל את השימוש בממשקי non-SDK באפליקציות ב-Android 9 (רמת API‏ 28). ‫Android 10 כולל רשימות מעודכנות של ממשקי non-SDK מוגבלים, שמבוססות על שיתוף פעולה עם מפתחי Android ועל הבדיקות הפנימיות האחרונות. המטרה שלנו היא לוודא שיש חלופות ציבוריות לפני שנחיל הגבלות על ממשקים שאינם SDK.

אם לא תטרגטו ל-Android 10 (רמת API‏ 29), יכול להיות שחלק מהשינויים האלה לא ישפיעו עליכם באופן מיידי. עם זאת, למרות שכרגע אפשר להשתמש בחלק מהממשקים שאינם חלק מ-SDK (בהתאם לרמת ה-API לטירגוט של האפליקציה), שימוש בשיטה או בשדה כלשהם שאינם חלק מ-SDK תמיד כרוך בסיכון גבוה להפסקת הפעולה של האפליקציה.

אם אתם לא בטוחים אם האפליקציה שלכם משתמשת בממשקים שאינם SDK, אתם יכולים לבצע בדיקה לאפליקציה כדי לגלות זאת. אם האפליקציה שלכם מסתמכת על ממשקים שאינם SDK, כדאי להתחיל לתכנן מעבר לחלופות SDK. עם זאת, אנחנו מבינים שיש אפליקציות שבהן יש תרחישי שימוש לגיטימיים בממשקים שאינם SDK. אם אין לכם אפשרות להשתמש בממשק שאינו ב-SDK עבור תכונה באפליקציה, עליכם לשלוח בקשה לממשק API ציבורי חדש.

מידע נוסף זמין במאמרים בנושא עדכונים בהגבלות על ממשקים שאינם ב-SDK ב-Android 10 והגבלות על ממשקים שאינם ב-SDK.

זיכרון משותף

הפורמט של מיפוי dalvik ב-‎ /proc/<pid>/maps השתנה ב-Ashmem,‏ מה שמשפיע על אפליקציות שמנתחות ישירות את קובץ המיפוי. מפתחי אפליקציות צריכים לבדוק את הפורמט של ‎ /proc/<pid>/maps במכשירים עם Android 10 ואילך, ולנתח אותו בהתאם אם האפליקציה מסתמכת על פורמטים של מפות dalvik.

אפליקציות שמיועדות ל-Android 10 לא יכולות להשתמש ישירות ב-ashmem (/dev/ashmem), ובמקום זאת הן צריכות לגשת לזיכרון משותף דרך המחלקה ASharedMemory של NDK. בנוסף, אפליקציות לא יכולות לבצע IOCTL ישירים לתיאורי קבצים קיימים של ashmem, אלא חייבות להשתמש במחלקה ASharedMemory של NDK או בממשקי ה-API של Android Java כדי ליצור אזורי זיכרון משותפים. השינוי הזה משפר את האבטחה והיציבות כשעובדים עם זיכרון משותף, וכך משפר את הביצועים והאבטחה של Android באופן כללי.

הוסרה הרשאת ההפעלה של ספריית הבית של האפליקציה

הפעלת קבצים מספריית הבית של האפליקציה עם הרשאות כתיבה היא הפרה של W^X. אפליקציות צריכות לטעון רק את הקוד הבינארי שמוטמע בקובץ ה-APK של האפליקציה.

אפליקציות לא מהימנות שמיועדות ל-Android 10 לא יכולות להפעיל את execve() ישירות בקבצים בספריית הבית של האפליקציה.

בנוסף, אפליקציות שמיועדות ל-Android 10 לא יכולות לשנות בזיכרון קוד הפעלה מקבצים שנפתחו באמצעות dlopen(), ולצפות שהשינויים האלה ייכתבו בדיסק, כי אי אפשר למפות את הספרייה PROT_EXEC באמצעות מתאר קובץ שניתן לכתיבה. זה כולל קבצים של אובייקטים משותפים (.so) עם העברות של טקסט.

‫Android runtime מקבל רק קובצי OAT שנוצרו על ידי המערכת

‫Android runtime‏ (ART) כבר לא מפעיל את dex2oat מתהליך האפליקציה. השינוי הזה אומר שמערכת ART תקבל רק קובצי OAT שהמערכת יצרה.

אכיפת נכונות של AOT ב-ART

בעבר, קומפילציה מראש (AOT) שבוצעה על ידי Android Runtime‏ (ART) יכלה לגרום לקריסות בזמן ריצה אם סביבת נתיב המחלקה לא הייתה זהה בזמן הקומפילציה ובזמן הריצה. ב-Android 10 ואילך, הקשרים של הסביבה תמיד צריכים להיות זהים, ולכן יש שינויים בהתנהגות:

  • טועני מחלקות מותאמים אישית – כלומר, טועני מחלקות שנכתבו על ידי אפליקציות, בניגוד לטועני מחלקות מחבילת dalvik.system – לא עוברים קומפילציה מראש (AOT). הסיבה לכך היא ש-ART לא יכול לדעת על הטמעה של חיפוש מחלקות בהתאמה אישית בזמן ריצה.
  • קובצי DEX משניים – כלומר, קובצי DEX שנטענים באופן ידני על ידי אפליקציות שלא נמצאות בקובץ ה-APK הראשי – עוברים קומפילציה של AOT ברקע. הסיבה לכך היא שהידור בשימוש הראשון עלול להיות יקר מדי, ולגרום לחביון לא רצוי לפני ההפעלה. הערה: מומלץ להשתמש בפיצולים באפליקציות ולהפסיק להשתמש בקובצי dex משניים.
  • ספריות משותפות ב-Android (הרשומות <library> ו-<uses-library> במניפסט של Android) מיושמות באמצעות היררכיית טועני מחלקות שונה מזו שנעשה בה שימוש בגרסאות קודמות של הפלטפורמה.

שינויים בהרשאות להצגת Intent במסך מלא

אפליקציות שמטרגטות את Android מגרסה 10 ואילך ומשתמשות בהתראות עם כוונה להצגת מסך מלא חייבות לבקש את ההרשאה USE_FULL_SCREEN_INTENT בקובץ המניפסט של האפליקציה. זו הרשאה רגילה, ולכן המערכת מעניקה אותה באופן אוטומטי לאפליקציה שביקשה אותה.

אם אפליקציה שמטרגטת Android 10 ואילך מנסה ליצור התראה עם Intent במסך מלא בלי לבקש את ההרשאה הנדרשת, המערכת מתעלמת מה-Intent במסך מלא ומציגה את הודעת היומן הבאה:

Package your-package-name: Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission

תמיכה במכשירים מתקפלים

‫Android 10 כוללת שינויים שתומכים במכשירים מתקפלים ובמכשירים עם מסך גדול.

כשמריצים אפליקציה ב-Android 10, השיטות onResume() ו- onPause() פועלות בצורה שונה. כשכמה אפליקציות מופיעות בו-זמנית במצב חלונות מרובים או במצב ריבוי מסכים, כל הפעילויות העליונות שניתן להתמקד בהן במחסניות גלויות נמצאות במצב 'הפעלה מחדש', אבל רק אחת מהן, הפעילות העליונה ביותר שהופעלה מחדש, נמצאת בפוקוס. כשמריצים את האפליקציה בגרסאות קודמות ל-Android 10, אפשר להפעיל מחדש רק פעילות אחת במערכת בכל פעם, וכל שאר הפעילויות הגלויות מושהות.

אל תתבלבלו בין 'מיקוד' לבין הפעילות 'העליונה ביותר שהופעלה מחדש'. המערכת מקצה עדיפויות לפעילויות על סמך סדר ה-Z, כדי לתת עדיפות גבוהה יותר לפעילויות שהמשתמש יצר איתן אינטראקציה אחרונה. אפשר להפעיל מחדש פעילות, אבל לא להתמקד בה (לדוגמה, אם מגדילים את חלונית ההתראות).

ב-Android 10 (רמת API‏ 29) ואילך, אפשר להירשם לקריאה חוזרת (callback) של onTopResumedActivityChanged() כדי לקבל התראה כשהפעילות מקבלת או מאבדת את המיקום העליון שבו היא מושהית. זה שווה ערך למצב ההפעלה לפני Android 10, ויכול להיות שימושי כרמז אם האפליקציה שלכם משתמשת במשאבים בלעדיים או במשאבים מסוג singleton שאולי צריך לשתף עם אפליקציות אחרות.

גם ההתנהגות של מאפיין המניפסט resizeableActivity השתנתה. אם אפליקציה מגדירה את resizeableActivity=false ב-Android 10 (רמת API‏ 29) ואילך, יכול להיות שהיא תועבר למצב תאימות כשגודל המסך הזמין משתנה, או אם האפליקציה מועברת ממסך אחד למסך אחר.

אפליקציות יכולות להשתמש במאפיין android:minAspectRatio שנוסף ב-Android 10, כדי לציין את יחסי הגובה-רוחב של המסך שהאפליקציה תומכת בהם.

החל מגרסה 3.5, כלי האמולטור של Android Studio כולל מכשירים וירטואליים בגודל 7.3 אינץ' ו-8 אינץ' לבדיקת הקוד במסכים גדולים יותר.

מידע נוסף מופיע במאמר בנושא עיצוב אפליקציות למכשירים מתקפלים.