מערכת Android 10 כוללת שינויים בהתנהגות שעשויים להשפיע על האפליקציה שלכם. השינויים שמפורטים בדף הזה חלים על האפליקציה כשהיא פועלת ב-Android 10, ללא קשר ל-targetSdkVersion
של האפליקציה. מומלץ לבדוק את האפליקציה ולשנות אותה לפי הצורך כדי שתתמוך בשינויים האלה בצורה תקינה.
אם הערך של targetSdkVersion של האפליקציה הוא 29
ואילך, תצטרכו גם לתמוך בשינויים נוספים. מומלץ לקרוא את המאמר שינויים בהתנהגות של אפליקציות שמטרגטות משתמשים בני 29 ומעלה כדי לקבל פרטים נוספים.
הערה: בנוסף לשינויים שמפורטים בדף הזה, ב-Android 10 יש מספר רב של שינויים והגבלות שמבוססים על פרטיות, כולל:
- גישה ברקע למיקום של המכשיר
- התחלות של פעילות ברקע
- מידע על תחומי העניין של אנשי הקשר
- רנדומיזציה של כתובת MAC
- מטא-נתונים של מצלמה
- מודל הרשאות
השינויים האלה משפיעים על כל האפליקציות ומשפרים את פרטיות המשתמשים. למידע נוסף על תמיכה בשינויים האלה, אפשר לעיין בדף שינויים בנושא פרטיות.
הגבלות על ממשק שאינו SDK
כדי לשמור על יציבות ותאימות של האפליקציות, הפלטפורמה התחילה להגביל את הממשקים שאינם 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.
ניווט באמצעות תנועות
החל מגרסה 10 של Android, המשתמשים יכולים להפעיל ניווט באמצעות תנועות בכל המכשיר. אם משתמש מפעיל את הניווט באמצעות תנועות, הדבר משפיע על כל האפליקציות במכשיר, גם אם האפליקציה מטרגטת את רמת ה-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/
.
כדי לשמור על תאימות, קישורי ה-symlink מסופקים בנתיבים הישנים. לדוגמה, /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()
. עם זאת, מומלץ מאוד להגדיר אותה חזרה ל-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()
. - סט הצפנות
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 שולחת כוונה עם הפעולה ACTION_MANAGE_OVERLAY_PERMISSION
, המערכת דוחה את הבקשה באופן אוטומטי ומעבירה את המשתמש למסך הגדרות שבו כתוב שההרשאה לא מותרת כי היא מאטה את המכשיר. אם אפליקציה במכשיר Go קוראת ל-Settings.canDrawOverlays()
, השיטה תמיד מחזירה את הערך false. שוב, ההגבלות האלה לא חלות על אפליקציות שקיבלו את ההרשאה SYSTEM_ALERT_WINDOW
לפני שהמכשיר שודרג ל-Android 10.
אזהרות לגבי אפליקציות שמטרגטות גרסאות ישנות יותר של Android
במכשירים עם Android 10 ואילך, המשתמשים מקבלים אזהרה בפעם הראשונה שהם מריצים אפליקציה שמטרגטת Android 5.1 (רמת API 22) ומטה. אם האפליקציה דורשת מהמשתמש להעניק הרשאות, הוא גם מקבל הזדמנות לשנות את ההרשאות של האפליקציה לפני שהיא תורשה לפעול בפעם הראשונה.
עקב דרישות ה-API לטירגוט של Google Play, המשתמשים רואים את האזהרות האלה רק כשהם מפעילים אפליקציה שלא עודכנה לאחרונה. לגבי אפליקציות שמופצות דרך חנויות אחרות, דרישות דומות לגבי ממשקי API לטירגוט ייכנסו לתוקף במהלך שנת 2019. למידע נוסף על הדרישות האלה, ראו הרחבת הדרישות לרמת ה-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 – ב-Android 10 יש מעקב מדויק אחרי השימוש באפליקציות באמצעות UsageStats כשמשתמשים באפליקציות במצב מסך מפוצל או בחלון בחלון. בנוסף, ב-Android 10 מתבצע מעקב תקין אחרי השימוש באפליקציות אינסטנט.
לכל אפליקציה בנפרד – ב-Android 10 אפשר להגדיר תצוגה בגווני אפור לכל אפליקציה בנפרד.
מצב הסחת דעת לכל אפליקציה – ב-Android 10 אפשר להגדיר אפליקציות באופן סלקטיבי למצב 'הסחת דעת', שבו ההתראות שלהן מושבתות והן לא מופיעות כאפליקציות מוצעות.
שינויים בחיבור HTTPS
אם אפליקציה שפועלת ב-Android 10 מעבירה את null
אל setSSLSocketFactory()
, מתרחש אירוע IllegalArgumentException
. בגרסאות קודמות, העברת null
אל setSSLSocketFactory()
הייתה זהה להעברת המפעל שמוגדר כברירת מחדל הנוכחי.
הספרייה 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"}
, במקום {"", "x"}
שהיה מוחזר בגרסאות ישנות יותר של Android.
עכשיו הפונקציה "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 ומטה, האובייקט יקרא בצורה נכונה על ידי אפליקציות שמטרגטות לרמת API 24 ומעלה, ולהפך.
שינויים ב-java.io.FileChannel.map()
החל מגרסה Android 10, אין תמיכה ב-FileChannel.map()
בקבצים לא סטנדרטיים, כמו /dev/zero
, שאי אפשר לשנות את הגודל שלהם באמצעות truncate()
. בגרסאות קודמות של Android, המערכת 'בלעה' את הערך של errno שהוחזר על ידי truncate()
, אבל ב-Android 10 מתרחשת השלכה של IOException. אם אתם זקוקים להתנהגות הישנה, עליכם להשתמש בקוד מקומי.