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 ציבורי חדש.
מידע נוסף זמין במאמרים Updates to non-SDK interface restrictions in Android 10 וRestrictions on non-SDK interfaces.
ניווט באמצעות תנועות
החל מ-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/…
כנתיבים תקינים.
ספריות/קבצים בינאריים של המערכת שממופים לזיכרון להרצה בלבד
החל מ-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
עםSSLHandshakeException
בגרסאות קודמות של Android, המופעים האלה מפעיליםSSLProtocolException
במקום זאת ב-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 לטירגוט, המשתמשים רואים את האזהרות האלה רק כשהם מפעילים אפליקציה שלא עודכנה לאחרונה. במהלך שנת 2019, נכנסות לתוקף דרישות דומות לגבי רמת ה-API לטירגוט באפליקציות שמופצות דרך חנויות אחרות. למידע נוסף על הדרישות האלה, אפשר לעיין במאמר הרחבת הדרישות בנושא רמת ה-API לטירגוט בשנת 2019.
הוסרו סטים של אלגוריתמים להצפנה (cipher suite) מסוג SHA-2 CBC
חבילות ההצפנה הבאות של SHA-2 CBC הוסרו מהפלטפורמה:
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
חבילות ההצפנה האלה פחות מאובטחות מחבילות הצפנה דומות שמשתמשות ב-GCM, ורוב השרתים תומכים גם בגרסאות GCM וגם בגרסאות CBC של חבילות ההצפנה האלה, או שלא תומכים באף אחת מהן.
שימוש באפליקציות
ב-Android 10 נוספו שינויים בהתנהגות שקשורים לשימוש באפליקציות:
שיפורים בשימוש באפליקציה UsageStats – <0x0 בנוסף, ב-Android 10 מתבצע מעקב מדויק אחר השימוש באפליקציות אינסטנט.
גווני אפור לכל אפליקציה – ב-Android 10 אפשר להגדיר מצב תצוגה בגווני אפור לכל אפליקציה בנפרד.
Per-app distraction state – ב-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 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)
מחזירהNullPointerException
, היא לא מתקשרת יותר אלreset()
ב-Matcher
. השגיאה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. אם אתם צריכים את ההתנהגות הישנה, אתם צריכים להשתמש בקוד מקומי.