Android 10 כולל שינויים בהתנהגות שעשויים להשפיע על האפליקציה שלכם. השינויים שמפורטים בדף הזה רלוונטיים לאפליקציה שלכם כשהיא פועלת ב-Android 10, בלי קשר ל-targetSdkVersion של האפליקציה. מומלץ לבדוק את האפליקציה ולשנות אותה לפי הצורך כדי לתמוך בשינויים האלה בצורה תקינה.
אם targetSdkVersion של האפליקציה הוא 29 ומעלה, תצטרכו גם לתמוך בשינויים נוספים. פרטים נוספים זמינים במאמר בנושא שינויים בהתנהגות של אפליקציות שמיועדות לגרסה 29.
הערה: בנוסף לשינויים שמפורטים בדף הזה, ב-Android 10 הוכנסו מספר רב של שינויים והגבלות שקשורים לפרטיות, כולל השינויים הבאים:
- גישה למיקום המכשיר ברקע
- התחלות של פעילות ברקע
- מידע על הקשרים עם אנשי הקשר
- הקצאה אקראית של כתובת MAC
- מטא-נתונים של המצלמה
- מודל הרשאות
השינויים האלה משפיעים על כל האפליקציות ומשפרים את פרטיות המשתמשים. מידע נוסף על התמיכה בשינויים האלה זמין בדף שינויים בפרטיות.
הגבלות על ממשקים שאינם SDK
כדי לשפר את היציבות והתאימות של האפליקציות, הפלטפורמה התחילה להגביל את השימוש בממשקים שאינם חלק מ-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.
ניווט באמצעות תנועות
החל מ-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/. קריסה שקשורה להרשאת הפעלה בלבד
כוללת את הודעת הביטול הבאה:
Cause: execute-only (no-read) memory access error; likely due to data in .text.
כדי לעקוף את הבעיה הזו ולבצע פעולות כמו הכלי לבדיקת זיכרון, אפשר לסמן פלחים עם הרשאת הפעלה בלבד כפלחים עם הרשאות קריאה והפעלה על ידי קריאה ל-mprotect(). עם זאת, אנחנו ממליצים מאוד להחזיר את ההגדרה ל'הרשאת גישה להפעלה בלבד' לאחר מכן, כי הגדרת הרשאת הגישה הזו מספקת הגנה טובה יותר לאפליקציה ולמשתמשים.
אבטחה
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מופעלתSSLEngineSSLHandshakeExceptionבגרסאות קודמות של Android, המופעלתSSLEngineמופעלתSSLEngineSSLProtocolExceptionבמקום זאת ב-Android 10 ואילך. - אין תמיכה במצב 0-RTT.
אם רוצים, אפשר להתקשר אל SSLContext.getInstance("TLSv1.2") כדי לקבל SSLContext שבו TLS 1.3 מושבת.
אפשר גם להפעיל או להשבית גרסאות של פרוטוקולים לכל חיבור בנפרד באמצעות קריאה ל-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(). - הסט של האלגוריתמים להצפנה
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 Direct לא נשמרים:
אם האפליקציה הסתמכה על קבלת השידורים האלה בזמן ההרשמה כי הם היו קבועים, צריך להשתמש בשיטה המתאימה 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
חבילות ההצפנה הבאות של 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
חבילות ההצפנה האלה פחות מאובטחות מחבילות הצפנה דומות שמשתמשות ב-GCM, ורוב השרתים תומכים גם בגרסאות GCM וגם בגרסאות CBC של חבילות ההצפנה האלה, או שלא תומכים באף אחת מהן.
שימוש באפליקציות
Android 10 כוללת את השינויים הבאים בהתנהגות שקשורים לשימוש באפליקציות:
שיפורים בשימוש באפליקציה UsageStats – <0x בנוסף, ב-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 אם הן הופעלו אחרי קריאה ל-method end().
ב-Android 10, ה-methods האלה מחזירות במקום זאת את הערך 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 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כללי יותר אם האינדקס של הקבוצה חורג מהגבולות. בעבר, ה-methods האלה החזירו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.