ב-Android 10 יש שינויים בהתנהגות שעשויים להשפיע על האפליקציה שלכם. השינויים שמפורטים בדף הזה רלוונטיים לאפליקציה כשהיא פועלת ב-Android 10, בלי קשר ל-targetSdkVersion של האפליקציה. כדאי לבדוק את האפליקציה ולשנות אותה לפי הצורך כדי לתמוך בשינויים האלה כמו שצריך.
אם ה-targetSdkVersion של האפליקציה הוא 29 ומעלה, תצטרכו לתמוך גם בשינויים נוספים. חשוב לקרוא את המאמר שינויים בהתנהגות של אפליקציות שמטרגטות את גרסה 29 כדי לקבל פרטים נוספים.
הערה: בנוסף לשינויים שמפורטים בדף הזה, ב-Android 10 יש הרבה שינויים והגבלות שקשורים לפרטיות, כולל:
- גישה ברקע למיקום המכשיר
- הפעילות ברקע מתחילה
- מידע על מידת הקרבה לאנשי קשר
- רנדומיזציה של כתובות MAC
- מטא-נתונים של המצלמה
- מודל ההרשאות
השינויים האלה משפיעים על כל האפליקציות ומשפרים את פרטיות המשתמשים. מידע נוסף על תמיכה בשינויים האלה זמין בדף שינויים בפרטיות.
הגבלות על ממשקים שאינם SDK
כדי להבטיח את היציבות והתאימות של האפליקציה, הפלטפורמה התחילה להגביל את ממשקי ה-API שאינם SDK שהאפליקציה יכולה להשתמש בהם ב-Android 9 (רמת API 28). ב-Android 10 יש רשימות מעודכנות של ממשקים מוגבלים שאינם SDK, שמבוססות על שיתוף פעולה עם מפתחי Android ועל הבדיקות הפנימיות האחרונות. המטרה שלנו היא לוודא שקיימות חלופות ציבוריות לפני שאנחנו מגבילים ממשקים שאינם SDK.
אם אתם לא מתכננים לטרגט ל-Android 10 (רמת API 29), יכול להיות שחלק מהשינויים האלה לא ישפיעו עליכם באופן מיידי. עם זאת, למרות שכרגע אפשר להשתמש בחלק מהממשקים שאינם SDK (בהתאם לרמת ה-API המיועדת של האפליקציה), שימוש בכל שיטה או שדה שאינם SDK תמיד כרוך בסיכון גבוה לפגיעה באפליקציה.
אם אתם לא בטוחים אם באפליקציה שלכם נעשה שימוש בממשקים שאינם SDK, אתם יכולים לבדוק את האפליקציה כדי לברר זאת. אם האפליקציה שלכם מסתמכת על ממשקים שאינם SDK, כדאי להתחיל לתכנן מעבר לחלופות SDK. עם זאת, אנחנו מבינים שיש אפליקציות שבהן יש תרחישי שימוש לגיטימיים לשימוש בממשקים שאינם SDK. אם אתם לא מוצאים חלופה לשימוש בממשק שאינו SDK לתכונה באפליקציה, אתם צריכים לבקש API ציבורי חדש.
מידע נוסף זמין במאמרים עדכונים להגבלות על ממשקים שאינם SDK ב-Android 10 והגבלות על ממשקים שאינם SDK.
ניווט באמצעות תנועות
החל מ-Android 10, המשתמשים יכולים להפעיל ניווט באמצעות תנועות בכל המכשיר. אם משתמש מפעיל ניווט באמצעות תנועות, זה משפיע על כל האפליקציות במכשיר, גם אם האפליקציה לא מטרגטת את רמת ה-API 29. לדוגמה, אם המשתמש מחליק פנימה מקצה המסך, המערכת מפרשת את התנועה הזו כניווט אחורה, אלא אם אפליקציה מבטלת באופן ספציפי את התנועה הזו בחלקים מסוימים של המסך.
כדי שהאפליקציה תתאים לניווט באמצעות תנועות, צריך להרחיב את תוכן האפליקציה מקצה לקצה ולטפל בתנועות שמתנגשות בצורה מתאימה. למידע נוסף, עיינו במסמכי התיעוד בנושא ניווט באמצעות תנועות.
NDK
Android 10 כוללת את השינויים הבאים ב-NDK.
אובייקטים משותפים לא יכולים להכיל העברות טקסט
ב-Android 6.0 (רמת API 23) נאסר השימוש בהעברות טקסט באובייקטים משותפים. צריך לטעון את הקוד כמו שהוא, בלי לשנות אותו. השינוי הזה משפר את זמני הטעינה של האפליקציה ואת האבטחה.
SELinux אוכף את ההגבלה הזו על אפליקציות שמטרגטות ל-Android 10 ואילך. אם האפליקציות האלה ימשיכו להשתמש באובייקטים משותפים שמכילים העברות טקסט, יש סיכון גבוה שהן יפסיקו לפעול.
שינויים בספריות Bionic ובנתיבים של מקשרים דינמיים
החל מ-Android 10, כמה נתיבים הם קישורים סמליים במקום קבצים רגילים. אפליקציות שמסתמכות על כך שהנתיבים הם קבצים רגילים עלולות להפסיק לפעול:
/system/lib/libc.so->/apex/com.android.runtime/lib/bionic/libc.so/system/lib/libm.so->/apex/com.android.runtime/lib/bionic/libm.so/system/lib/libdl.so->/apex/com.android.runtime/lib/bionic/libdl.so/system/bin/linker->/apex/com.android.runtime/bin/linker
השינויים האלה חלים גם על גרסאות 64 ביט של הקובץ, כאשר lib/ מוחלף ב-lib64/.
כדי לשמור על תאימות, הקישורים הסימבוליים נמצאים בנתיבים הישנים. לדוגמה, /system/lib/libc.so הוא קישור סימבולי אל /apex/com.android.runtime/lib/bionic/libc.so. לכן dlopen(“/system/lib/libc.so”) ממשיך לפעול, אבל אפליקציות יזהו את ההבדל כשהן ינסו לבדוק את הספריות שנטענו על ידי קריאת /proc/self/maps או קובץ דומה. זה לא קורה בדרך כלל, אבל גילינו שיש אפליקציות שעושות את זה כחלק מתהליך ההגנה שלהן מפני פריצות. אם כן, צריך להוסיף את הנתיבים של /apex/… כנתיבים תקינים לקובצי Bionic.
קבצים בינאריים/ספריות של המערכת ממופים לזיכרון להפעלה בלבד
החל מ-Android 10, מקטעים של קובצי מערכת בינאריים וספריות שניתנים להפעלה ממופים לזיכרון להפעלה בלבד (לא לקריאה) כטכניקה להקשחת המערכת נגד התקפות של שימוש חוזר בקוד. אם האפליקציה מבצעת פעולות קריאה בקטעי זיכרון שמסומנים כ"להפעלה בלבד" – בין אם בגלל באג, נקודת חולשה או בדיקת זיכרון מכוונת – המערכת שולחת אות SIGSEGV לאפליקציה.
כדי לזהות אם ההתנהגות הזו גרמה לקריסה, אפשר לבדוק את קובץ ה-tombstone הקשור ב-/data/tombstones/. קריסה שקשורה ל-execute-only מכילה את הודעת הביטול הבאה:
Cause: execute-only (no-read) memory access error; likely due to data in .text.
כדי לעקוף את הבעיה הזו ולבצע פעולות כמו הכלי לבדיקת זיכרון, אפשר לסמן קטעים להפעלה בלבד כקריאה+הפעלה באמצעות קריאה ל-mprotect(). עם זאת, מומלץ מאוד להחזיר את ההגדרה ל-execute-only לאחר מכן, כי הגדרת הרשאת הגישה הזו מספקת הגנה טובה יותר לאפליקציה ולמשתמשים.
אבטחה
Android 10 כוללת את שינויי האבטחה הבאים.
TLS 1.3 מופעל כברירת מחדל
ב-Android מגרסה 10 ואילך, TLS 1.3 מופעל כברירת מחדל לכל חיבורי ה-TLS. הנה כמה פרטים חשובים על ההטמעה של TLS 1.3:
- אי אפשר להתאים אישית את הסטים של אלגוריתמים להצפנה (cipher suite) של TLS 1.3. הסטים של אלגוריתמים להצפנה (cipher suite) שנתמכים ב-TLS 1.3 תמיד מופעלים כש-TLS 1.3 מופעל. כל ניסיון להשבית אותם באמצעות קריאה ל-
setEnabledCipherSuites()לא יצליח. - כשמתנהל משא ומתן על TLS 1.3,
HandshakeCompletedListenerאובייקטים נקראים לפני שהסשנים מתווספים למטמון הסשנים. (ב-TLS 1.2 ובגרסאות קודמות אחרות, האובייקטים האלה נקראים אחרי שהסשנים נוספים למטמון הסשנים). - במצבים מסוימים שבהם מופעים של
SSLEngineזורקיםSSLHandshakeExceptionבגרסאות קודמות של Android, המופעים האלה זורקיםSSLProtocolExceptionב-Android מגרסה 10 ואילך. - אין תמיכה במצב 0-RTT.
אם רוצים, אפשר לקבל SSLContext שבו TLS 1.3 מושבת, באמצעות קריאה ל-SSLContext.getInstance("TLSv1.2").
אפשר גם להפעיל או להשבית גרסאות של פרוטוקולים לכל חיבור בנפרד, על ידי קריאה ל-setEnabledProtocols() באובייקט המתאים.
אישורים שנחתמו באמצעות SHA-1 לא נחשבים מהימנים ב-TLS
ב-Android 10, אישורים שמשתמשים באלגוריתם הגיבוב SHA-1 לא נחשבים מהימנים בחיבורי TLS. רשויות אישורים בסיסיות לא הנפיקו אישור כזה מאז 2016, והן כבר לא מהימנות ב-Chrome או בדפדפנים פופולריים אחרים.
כל ניסיון להתחבר לאתר שמציג אישור באמצעות SHA-1 ייכשל.
שינויים ושיפורים בהתנהגות של KeyChain
בדפדפנים מסוימים, כמו Google Chrome, המשתמשים יכולים לבחור אישור כששרת TLS שולח הודעה לבקשת אישור כחלק מלחיצת יד בפרוטוקול TLS. החל מ-Android 10, אובייקטים של KeyChain מכבדים את המנפיקים ואת הפרמטרים של מפרט המפתח כשמתבצעת קריאה ל-KeyChain.choosePrivateKeyAlias() כדי להציג למשתמשים בקשה לבחירת אישור. באופן ספציפי, ההנחיה הזו לא מכילה אפשרויות שלא תואמות למפרט השרת.
אם אין אישורים זמינים שהמשתמש יכול לבחור, למשל כשאין אישורים שתואמים למפרט השרת או כשלא מותקנים אישורים במכשיר, הבקשה לבחירת אישור לא מופיעה בכלל.
בנוסף, ב-Android מגרסה 10 ואילך לא צריך להגדיר נעילת מסך במכשיר כדי לייבא מפתחות או אישורי CA לאובייקט KeyChain.
שינויים אחרים ב-TLS ובקריפטוגרפיה
בספריות ה-TLS והקריפטוגרפיה בוצעו כמה שינויים קלים שנכנסים לתוקף ב-Android 10:
- הצפנים AES/GCM/NoPadding ו-ChaCha20/Poly1305/NoPadding מחזירים גודלי שטח אחסון זמני מדויקים יותר מ-
getOutputSize(). - סט האלגוריתמים להצפנה (cipher suite)
TLS_FALLBACK_SCSVמושמט מניסיונות החיבור עם פרוטוקול מקסימלי של TLS 1.2 ומעלה. בגלל שיפורים בהטמעות של שרתי TLS, אנחנו לא ממליצים לנסות חזרה למצב קודם חיצוני ל-TLS. במקום זאת, מומלץ להסתמך על משא ומתן על גרסת TLS. - ChaCha20-Poly1305 הוא כינוי ל-ChaCha20/Poly1305/NoPadding.
- שמות מארחים עם נקודות בסוף לא נחשבים לשמות מארחים תקינים של SNI.
- התוסף supported_signature_algorithms ב-
CertificateRequestנלקח בחשבון כשבוחרים מפתח חתימה לתגובות של אישורים. - אפשר להשתמש במפתחות חתימה אטומים, כמו אלה מ-Android Keystore, עם חתימות RSA-PSS ב-TLS.
שידורי Wi-Fi ישיר
ב-Android 10, השידורים הבאים שקשורים ל-Wi-Fi ישיר לא נשמרים:
אם האפליקציה שלכם הסתמכה על קבלת השידורים האלה בזמן הרישום כי הם היו דביקים, השתמשו במקום זאת בשיטת get() המתאימה בזמן האתחול כדי לקבל את המידע.
יכולות Wi-Fi Aware
ב-Android 10 נוספה תמיכה שמאפשרת ליצור בקלות שקעי TCP/UDP באמצעות נתיבי נתונים של Wi-Fi Aware. כדי ליצור שקע TCP/UDP שמתחבר ל-ServerSocket, מכשיר הלקוח צריך לדעת את כתובת ה-IPv6 ואת היציאה של השרת. בעבר, היה צריך להעביר את המידע הזה מחוץ לפס, למשל באמצעות הודעות בשכבה 2 של BT או Wi-Fi Aware, או לגלות אותו בתוך הפס באמצעות פרוטוקולים אחרים, כמו mDNS. ב-Android 10, אפשר להעביר את המידע כחלק מהגדרת הרשת.
השרת יכול לבצע אחת מהפעולות הבאות:
- מאתחלים את
ServerSocketומגדירים או מקבלים את היציאה שבה רוצים להשתמש. - ציינו את פרטי היציאה כחלק מהבקשה לאחזור מהרשת של Wi-Fi Aware.
בדוגמת הקוד הבאה אפשר לראות איך לציין את פרטי היציאה כחלק מהבקשה לאחזור מהרשת:
Kotlin
val ss = ServerSocket() val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("some-password") .setPort(ss.localPort) .build() val myNetworkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(ns) .build()
Java
ServerSocket ss = new ServerSocket(); WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier .Builder(discoverySession, peerHandle) .setPskPassphrase(“some-password”) .setPort(ss.getLocalPort()) .build(); NetworkRequest myNetworkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(ns) .build();
לאחר מכן, הלקוח מבצע בקשה לאחזור מהרשת של Wi-Fi Aware כדי לקבל את כתובת ה-IPv6 ואת היציאה שסופקה על ידי השרת:
Kotlin
val callback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { ... } override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) { ... } override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { ... val ti = networkCapabilities.transportInfo if (ti is WifiAwareNetworkInfo) { val peerAddress = ti.peerIpv6Addr val peerPort = ti.port } } override fun onLost(network: Network) { ... } }; connMgr.requestNetwork(networkRequest, callback)
Java
callback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { ... } @Override public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) { ... } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { ... TransportInfo ti = networkCapabilities.getTransportInfo(); if (ti instanceof WifiAwareNetworkInfo) { WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti; Inet6Address peerAddress = info.getPeerIpv6Addr(); int peerPort = info.getPort(); } } @Override public void onLost(Network network) { ... } }; connMgr.requestNetwork(networkRequest, callback);
SYSTEM_ALERT_WINDOW במכשירי Go
אפליקציות שפועלות במכשירי Android 10 (מהדורת Go) לא יכולות לקבל את ההרשאה
SYSTEM_ALERT_WINDOW. הסיבה לכך היא ששרטוט חלונות שכבת-על צורך הרבה זיכרון, וזה פוגע במיוחד בביצועים של מכשירי Android עם זיכרון מועט.
אם אפליקציה שפועלת במכשיר עם מהדורת Go עם Android בגרסה 9 או גרסה קודמת מקבלת את ההרשאה SYSTEM_ALERT_WINDOW, האפליקציה שומרת על ההרשאה גם אם המכשיר משודרג ל-Android בגרסה 10. עם זאת, אפליקציות שעדיין לא קיבלו את ההרשאה הזו לא יוכלו לקבל אותה אחרי שדרוג המכשיר.
אם אפליקציה במכשיר Go שולחת Intent עם הפעולה ACTION_MANAGE_OVERLAY_PERMISSION, המערכת דוחה את הבקשה באופן אוטומטי ומעבירה את המשתמש למסך הגדרות שבו כתוב שההרשאה לא מותרת כי היא מאטה את המכשיר. אם אפליקציה במכשיר Go קוראת ל-Settings.canDrawOverlays(), השיטה תמיד מחזירה את הערך false. שוב, ההגבלות האלה לא חלות על אפליקציות שקיבלו את ההרשאה SYSTEM_ALERT_WINDOW לפני שהמכשיר שודרג ל-Android 10.
אזהרות לגבי אפליקציות שמטרגטות גרסאות ישנות יותר של Android
במכשירים עם Android בגרסה 10 ומעלה, המשתמשים מקבלים אזהרה בפעם הראשונה שהם מפעילים אפליקציה שמטרגטת ל-Android 5.1 (רמת API 22) ומטה. אם האפליקציה דורשת מהמשתמש להעניק הרשאות, המשתמש מקבל גם הזדמנות לשנות את ההרשאות של האפליקציה לפני שהיא מופעלת בפעם הראשונה.
בגלל הדרישות של Google Play לגבי רמת ה-API לטירגוט, המשתמשים רואים את האזהרות האלה רק כשהם מפעילים אפליקציה שלא עודכנה לאחרונה. באפליקציות שמופצות דרך חנויות אחרות, דרישות דומות לגבי רמת ה-API לטירגוט נכנסות לתוקף במהלך 2019. מידע נוסף על הדרישות האלה זמין במאמר הרחבת הדרישות של רמת ה-API המיועדת ב-2019.
הוסרו סטים של אלגוריתמים להצפנה (cipher suite) מסוג SHA-2 CBC
הסרנו מהפלטפורמה את הסטים הבאים של אלגוריתמים להצפנה (cipher suite) מסוג SHA-2 CBC:
TLS_RSA_WITH_AES_128_CBC_SHA256TLS_RSA_WITH_AES_256_CBC_SHA256TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
סטים אלגוריתמים להצפנה (cipher suite) אלה פחות מאובטחים מסטים דומים שמשתמשים ב-GCM, ורוב השרתים תומכים גם בגרסאות GCM וגם בגרסאות CBC של סטים אלגוריתמים להצפנה (cipher suite) אלה, או לא תומכים באף אחת מהן.
שימוש באפליקציות
ב-Android 10 יש את השינויים הבאים בהתנהגות שקשורים לשימוש באפליקציות:
שיפורים ב-UsageStats למעקב אחרי השימוש באפליקציות – ב-Android 10, המערכת עוקבת באופן מדויק אחרי השימוש באפליקציות באמצעות UsageStats כשהאפליקציות פועלות במצב מסך מפוצל או במצב 'תמונה בתוך תמונה'. בנוסף, ב-Android 10 מתבצע מעקב תקין אחרי השימוש באפליקציות ללא התקנה.
גווני אפור לכל אפליקציה – ב-Android 10 אפשר להגדיר מצב תצוגה של גווני אפור לכל אפליקציה בנפרד.
מצב הסחת דעת לכל אפליקציה – ב-Android 10 אפשר להגדיר אפליקציות באופן סלקטיבי ל "מצב הסחת דעת", שבו ההתראות שלהן מושתקות והן לא מופיעות כאפליקציות מוצעות.
השעיה והפעלה – ב-Android 10, אפליקציות מושעות לא יכולות להפעיל אודיו.
שינויים בחיבור HTTPS
אם אפליקציה שפועלת ב-Android 10 מעבירה את null אל
setSSLSocketFactory(),
מתרחשת שגיאה מסוג IllegalArgumentException. בגרסאות קודמות, העברת null אל setSSLSocketFactory() הייתה משפיעה באותו אופן כמו העברת ברירת המחדל הנוכחית של ה-factory.
הספרייה android.preference הוצאה משימוש
הספרייה android.preference הוצאה משימוש החל מ-Android 10.
במקום זאת, המפתחים צריכים להשתמש בספריית ההעדפות של AndroidX, שהיא חלק מ-Android Jetpack. כדי לקבל עזרה נוספת בהעברה ובפיתוח, כדאי לעיין במדריך ההגדרות המעודכן, באפליקציה לדוגמה שזמינה לכולם ובמאמרי העזרה.
שינויים בספריית כלי השירות של קובצי ZIP
ב-Android 10 יש את השינויים הבאים במחלקות בחבילה java.util.zip, שמטפלת בקובצי ZIP. השינויים האלה הופכים את ההתנהגות של הספרייה לעקבית יותר בין Android לבין פלטפורמות אחרות שמשתמשות ב-java.util.zip.
מנגנון ניפוח
בגרסאות קודמות, חלק מה-methods במחלקה Inflater זרקו שגיאת IllegalStateException אם הן הופעלו אחרי קריאה ל-end().
ב-Android 10, השיטות האלה מציגות במקום זאת NullPointerException.
ZipFile
ב-Android מגרסה 10 ואילך, ה-constructor של
ZipFile
שמקבל ארגומנטים מסוג File, int ו-Charset לא זורק
ZipException אם קובץ ה-ZIP שסופק
לא מכיל קבצים.
ZipOutputStream
ב-Android מגרסה 10 ואילך, השיטה
finish() ב-
ZipOutputStream לא גורמת ל-
ZipException אם היא מנסה לכתוב
זרם פלט לקובץ ZIP שלא מכיל קבצים.
שינויים במצלמה
באפליקציות רבות שמשתמשות במצלמה, ההנחה היא שאם המכשיר מוגדר לאורך, גם המכשיר הפיזי נמצא בכיוון לאורך, כפי שמתואר בקטע כיוון המצלמה. בעבר זו הייתה הנחה בטוחה, אבל המצב השתנה עם התרחבות גורמי הצורה הזמינים, כמו מכשירים מתקפלים. ההנחה הזו במכשירים האלה יכולה להוביל לתצוגה מסובבת או מוקטנת/מוגדלת (או גם וגם) באופן שגוי של תצוגת הצילום במצלמה.
באפליקציות שמטרגטות ל-API ברמה 24 ומעלה, צריך להגדיר במפורש את android:resizeableActivity ולספק את הפונקציונליות הנדרשת כדי לטפל בפעולות של ריבוי חלונות.
מעקב אחרי השימוש בסוללה
החל מ-Android 10, מערכת SystemHealthManager מאפסת את נתוני השימוש בסוללה בכל פעם שהמכשיר מנותק מהחשמל אחרי אירוע טעינה משמעותי. באופן כללי, אירוע טעינה משמעותי הוא אחד מהשניים: המכשיר נטען במלואו, או שהמכשיר נטען ממצב שבו הסוללה כמעט ריקה למצב שבו הסוללה כמעט מלאה.
בגרסאות Android שקדמו ל-Android 10, נתוני השימוש בסוללה אופסו בכל פעם שהמכשיר נותק מהחשמל, גם אם רמת הטעינה השתנתה רק במעט.
הוצאה משימוש של Android Beam
ב-Android 10 אנחנו מוציאים משימוש באופן רשמי את Android Beam, תכונה ישנה יותר לשיתוף נתונים בין מכשירים באמצעות תקשורת מטווח קצר (NFC). אנחנו גם מוציאים משימוש כמה ממשקי API קשורים של NFC. שותפים שהם יצרני מכשירים יכולים להמשיך להשתמש ב-Android Beam, אבל אנחנו כבר לא מפתחים את התכונה הזו. עם זאת, Android תמשיך לתמוך ביכולות ובממשקי API אחרים של NFC, ותרחישי שימוש כמו קריאה מתגים ותשלומים ימשיכו לפעול כצפוי.
שינוי בהתנהגות של java.math.BigDecimal.stripTrailingZeros()
הפונקציה BigDecimal.stripTrailingZeros() לא שומרת יותר אפסים נגררים כמקרה מיוחד אם ערך הקלט הוא אפס.
שינויים בהתנהגות של java.util.regex.Matcher ו-Pattern
התוצאה של split() שונתה כך שהיא לא תתחיל יותר ב-String ריק ("") כשיש התאמה ברוחב אפס בתחילת הקלט. ההגדרה הזו משפיעה גם על String.split(). לדוגמה, הפקודה "x".split("") מחזירה עכשיו את הערך {"x"}, ואילו בגרסאות ישנות יותר של Android היא החזירה את הערך {"", "x"}.
הפונקציה "aardvark".split("(?=a)" מחזירה עכשיו את הערך {"a", "ardv", "ark"} במקום {"", "a", "ardv", "ark"}.
שיפרנו גם את אופן הטיפול בחריגות שנובעות מארגומנטים לא תקינים:
- הפונקציה
appendReplacement(StringBuffer, String)מחזירה עכשיו את השגיאהIllegalArgumentExceptionבמקוםIndexOutOfBoundsExceptionאם המחרוזת החלופיתStringמסתיימת בלוכסן הפוך בודד, וזה לא חוקי. אותה חריגה נזרקת עכשיו אם ההחלפהStringמסתיימת ב-$. בעבר, לא הופיעה חריגה בתרחיש הזה. -
replaceFirst(null)לא קורא יותר ל-reset()ב-Matcherאם הוא זורקNullPointerException. השגיאהNullPointerExceptionמופיעה עכשיו גם כשאין התאמה. בעבר, האירוע הופעל רק כשהייתה התאמה. -
start(int group), end(int group)ו-group(int group)זורקים עכשיוIndexOutOfBoundsExceptionכללי יותר אם האינדקס של הקבוצה חורג מהגבולות. בעבר, השיטות האלה החזירו את השגיאהArrayIndexOutOfBoundsException.
זווית ברירת המחדל של GradientDrawable היא עכשיו TOP_BOTTOM
ב-Android 10, אם מגדירים
GradientDrawable
ב-XML ולא מספקים מדידת זווית, כיוון ההדרגתיות
מוגדר כברירת מחדל לערך
TOP_BOTTOM.
זהו שינוי מגרסאות קודמות של Android, שבהן ברירת המחדל הייתה LEFT_RIGHT.
כדי לעקוף את הבעיה, אם מעדכנים לגרסה העדכנית ביותר של AAPT2, הכלי מגדיר מדידת זווית של 0 לאפליקציות מדור קודם אם לא צוינה מדידת זווית.
רישום ביומן של אובייקטים שעברו סריאליזציה באמצעות SUID שמוגדר כברירת מחדל
החל מ-Android 7.0 (רמת API 24), הפלטפורמה תיקנה את ברירת המחדל של serialVersionUID לאובייקטים שניתנים לסריאליזציה. התיקון הזה לא השפיע על אפליקציות שמטרגטות את רמת ה-API 23 או רמה נמוכה יותר.
החל מ-Android 10, אם אפליקציה מטרגטת את רמת API 23 או רמה נמוכה יותר, ומתבססת על serialVersionUID הישן, השגוי והמוגדר כברירת מחדל, המערכת מתעדת אזהרה ביומן ומציעה תיקון קוד.
באופן ספציפי, המערכת מתעדת אזהרה אם כל התנאים הבאים מתקיימים:
- האפליקציה מטרגטת לרמת API 23 ומטה.
- כיתה עוברת סריאליזציה.
- הכיתה שעברה סריאליזציה משתמשת בברירת המחדל של
serialVersionUID, במקום להגדירserialVersionUIDבאופן מפורש. - ערך ברירת המחדל של
serialVersionUIDשונה מהערך שלserialVersionUIDאם האפליקציה הייתה מטרגטת לרמת API 24 ומעלה.
האזהרה הזו נרשמת פעם אחת לכל כיתה שמושפעת.
הודעת האזהרה כוללת הצעה לתיקון: להגדיר באופן מפורש את serialVersionUID לערך ברירת המחדל שהיה מחושב אם האפליקציה הייתה מטרגטת לרמת ה-API המיועדת 24 ומעלה. התיקון הזה מבטיח שאם אובייקט מהמחלקה הזו עובר סריאליזציה באפליקציה שמטרגטת לרמת ה-API המיועדת 23 או פחות, האובייקט ייקרא בצורה נכונה על ידי אפליקציות שמטרגטות לרמה 24 ומעלה, ולהפך.
שינויים ב-java.io.FileChannel.map()
החל מ-Android 10, אין תמיכה ב-FileChannel.map() לקבצים לא סטנדרטיים, כמו /dev/zero, שאי אפשר לשנות את הגודל שלהם באמצעות truncate(). בגרסאות קודמות של Android, המערכת התעלמה מה-errno שהוחזר על ידי truncate(), אבל ב-Android 10 נזרק IOException. אם אתם צריכים את ההתנהגות הישנה, אתם צריכים להשתמש בקוד Native.