לצד תכונות ויכולות חדשות, Android 8.0 (רמת API 26) שכולל מגוון שינויים בהתנהגות של המערכת וה-API. המסמך הזה מדגיש כמה מהשינויים העיקריים שעליך להבין ולהביא בחשבון באפליקציות שלכם.
רוב השינויים האלה משפיעים על כל האפליקציות, ללא קשר לגרסה של Android שהם מטרגטים. עם זאת, שינויים מסוימים ישפיעו רק על טירגוט לאפליקציות Android 8.0. כדי לשפר את הבהירות, הדף מחולק לשני קטעים: שינויים בכל האפליקציות ושינויים במיקוד לאפליקציות Android 8.0.
שינויים בכל האפליקציות
שינויי ההתנהגות האלה יחולו על
מגבלות ביצוע ברקע
אחד מהשינויים שמערכת Android 8.0 (רמת API 26) כוללת לשיפור חיי הסוללה, כשהאפליקציה נכנסת במטמון ללא פעילות רכיבים, המערכת משחררת את כל המנעולים של מצב שינה שהאפליקציה מחזיקה.
בנוסף, כדי לשפר את ביצועי המכשיר, המערכת מגבילה של אפליקציות שלא פועלות בחזית. פרטים נוספים:
- מעכשיו יש מגבלות על החופשיות של אפליקציות שפועלות ברקע הם יכולים לגשת לשירותים שפועלים ברקע.
- אפליקציות לא יכולות להשתמש במניפסטים שלהן כדי להירשם לרוב השידורים המרומזים (כלומר, שידורים שלא מטורגטים באופן ספציפי באפליקציה).
כברירת מחדל, ההגבלות האלה חלות רק על אפליקציות שמטרגטות ל-O. אבל, לפעמים המשתמשים יכולים להפעיל את ההגבלות האלה עבור כל אפליקציה במסך הגדרות, גם אם האפליקציה לא טירגטת את O.
Android 8.0 (רמת API 26) כולל גם את השינויים הבאים בשיטות ספציפיות:
- השיטה
startService()
גורמת עכשיוIllegalStateException
אם אפליקציה שמטרגט את Android 8.0, המערכת מנסה להשתמש בשיטה הזו במצב שבו אסור ליצור שירותים שפועלים ברקע. - השיטה החדשה
Context.startForegroundService()
מפעילה שירות שפועל בחזית. המערכת מאפשרת לאפליקציות כדי להתקשר אלContext.startForegroundService()
גם כשהאפליקציה ברקע. עם זאת, האפליקציה חייבת לקרוא ל-method שלstartForeground()
של השירות בתוך חמש שניות לאחר יצירת השירות.
מידע נוסף זמין במאמר הבא: מגבלות ביצוע ברקע.
מגבלות מיקום ברקע ב-Android
כדי לשמור על תקינות הסוללה, חוויית המשתמש ותקינות המערכת, אפליקציות ברקע מקבלות עדכוני מיקום בתדירות נמוכה יותר כשמשתמשים במכשיר עם Android 8.0. השינוי הזה בהתנהגות ישפיע על כל האפליקציות שמקבלים עדכוני מיקום, כולל Google Play Services.
השינויים האלה ישפיעו על ממשקי ה-API הבאים:
- ספק מיקום משולב (FLP)
- גבולות וירטואליים
- מדידות GNSS
- מנהל מיקומים
- מנהל Wi-Fi
כדי לוודא שהאפליקציה תפעל כצפוי, יש לבצע את השלבים הבאים:
- בדקו את הלוגיקה של האפליקציה וודאו שאתם משתמשים במיקום העדכני ביותר ממשקי API.
- צריך לבדוק שהאפליקציה מציגה את ההתנהגות שלך בכל שימוש מותאמת אישית.
- מומלץ להשתמש מיזוג ספק מיקום (FLP) או הגדרת גבולות וירטואליים לצורך טיפול בתרחישים לדוגמה התלויים המיקום הנוכחי של המשתמש.
למידע נוסף על השינויים האלה, אפשר לעיין במאמר מיקום ברקע מגבלות.
קיצורי דרך של אפליקציות
Android 8.0 (רמת API 26) כולל את השינויים הבאים במקשי קיצור של אפליקציות:
- מספר השידור של
com.android.launcher.action.INSTALL_SHORTCUT
אין יותר השפעה על האפליקציה שלך, כי היא מוגדרת עכשיו כפרטית ומרומזת שידור. במקום זאת, כדאי ליצור קיצור דרך לאפליקציה באמצעותrequestPinShortcut()
מהמחלקהShortcutManager
. ACTION_CREATE_SHORTCUT
Intent יכול עכשיו ליצור קיצורי דרך לאפליקציות שאתם מנהלים באמצעות כיתה אחת (ShortcutManager
). הכוונה הזו יכולה גם ליצור מקשי קיצור מדור קודם במרכז האפליקציות שלא יוצרים איתם אינטראקציהShortcutManager
בעבר, הכוונה הזו הייתה יכולה ליצור רק קיצורי דרך מדור קודם למרכז האפליקציות.- קיצורי דרך שנוצרו באמצעות
requestPinShortcut()
וקיצורי דרך שנוצרו בפעילות שמטפלתACTION_CREATE_SHORTCUT
Intent הם עכשיו מקשי קיצור מלאים לאפליקציות. לכן, עכשיו אפליקציות יכולות לעדכן אותן באמצעות השיטות ב-ShortcutManager
. - מקשי הקיצור הקודמים שומרים על הפונקציונליות שלהם מגרסאות קודמות של ב-Android, אבל צריך להמיר אותם לקיצורי דרך של אפליקציות באופן ידני באפליקציה.
מידע נוסף על השינויים בקיצורי הדרך של אפליקציות זמין במאמר הצמדת קיצורי דרך מדריך לתכונות של ווידג'טים.
לוקאלים ובינלאומיות
ב-Android 7.0 (רמת API 24) נוסף הקונספט של יכולת
לציין לוקאל קטגוריה שמוגדר כברירת מחדל, אבל חלק מממשקי ה-API המשיכו להשתמש
Locale.getDefault()
כללי
method, ללא ארגומנטים, כאשר הם היו אמורים להשתמש במקום זאת בלוקאל של קטגוריית ברירת המחדל DISPLAY
. ב-Android 8.0 (רמת API 26), הפרמטר
השיטות הבאות משתמשות עכשיו ב-Locale.getDefault(Category.DISPLAY)
במקום Locale.getDefault()
:
Locale.getDisplayScript(Locale)
גם
חוזר אל Locale.getDefault()
כאשר
צוין ערך displayScript עבור Locale
הארגומנט לא זמין.
שינויים נוספים שקשורים לאזור ולבינלאומיות ככה:
- אם מתקשרים אל
Currency.getDisplayName(null)
, מקבליםNullPointerException
, תואמת להתנהגות שתועדה. - ניתוח השם של אזור הזמן השתנה. בעבר,
מכשירי Android השתמשו בערך של שעון המערכת שנדגם בזמן ההפעלה
זמן לשמירה במטמון של שמות אזורי הזמן ששימשו לניתוח התאריך
פעמים. כתוצאה מכך, הניתוח עלול להיפגע אם המערכת
השעון היה שגוי בזמן האתחול או במקרים אחרים, נדירים יותר.
במקרים נפוצים, לוגיקת הניתוח משתמשת בICU הערך הנוכחי של שעון המערכת בעת ניתוח שמות של אזורי זמן. הזה מספקת תוצאות נכונות יותר, שעשויות להיות שונות מאלה של גרסאות Android כשהאפליקציה משתמשת בכיתות כמו
SimpleDateFormat
- מערכת Android 8.0 (רמת API 26) מעדכנת את גרסת ICU לגרסה 58.
חלונות התראות
אם אפליקציה משתמשת בSYSTEM_ALERT_WINDOW
משתמש באחד מסוגי החלונות הבאים כדי לנסות להציג
חלונות התראות מעל אפליקציות אחרות וחלונות מערכת:
...החלונות האלה מופיעים תמיד מתחת לחלונות שמשתמשים בהם
חלון TYPE_APPLICATION_OVERLAY
מהסוג הזה. אם אפליקציה מטרגטת ל-Android 8.0 (רמת API 26), האפליקציה משתמשת ב
TYPE_APPLICATION_OVERLAY
סוג החלון להצגת חלונות התראות.
מידע נוסף זמין במאמר סוגי חלונות נפוצים עבור הקטע 'חלונות התראות' בתוך השינויים בהתנהגות של אפליקציות שמטרגטת את Android 8.0.
קלט וניווט
בעקבות ההשקה של אפליקציות ל-Android ב-ChromeOS וגורמי צורה גדולים אחרים, כמו טאבלטים, אנחנו רואים עלייה מחודשת בשימוש בניווט באמצעות המקלדת אפליקציות ל-Android. ב-Android 8.0 (רמת API 26), טיפלנו מחדש באמצעות את המקלדת ככלי לקלט ניווט, וכתוצאה מכך מודל לחיזוי (prediction) של ניווט המבוסס על חצים וכרטיסיות.
באופן ספציפי, ביצענו את השינויים הבאים בפוקוס של הרכיבים התנהגות:
-
אם לא הגדרת צבעים עבור מצב התמקדות אובייקט
View
(החזית או הרקע שלו) שניתן לצייר), המסגרת מגדירה עכשיו צבע ברירת מחדל של הדגשה עבורView
. ההדגשה הזו היא באמצעות גלים שאפשר לצייר עליהם בהתאם לנושא של הפעילות.אם לא רוצים שאובייקט
View
ישתמש בברירת המחדל הזו להדגיש כשהוא מקבל את המיקוד, המאפייןandroid:defaultFocusHighlightEnabled
נשלח אלfalse
בקובץ ה-XML של הפריסה שמכיל אתView
, או להעביר אתfalse
אלsetDefaultFocusHighlightEnabled()
בלוגיקת ממשק המשתמש של האפליקציה. - כדי לבדוק איך קלט המקלדת משפיע על המיקוד של רכיב בממשק המשתמש, אפשר להפעיל את התכונה שרטוט > הצגת גבולות פריסה למפתחים. ב-Android 8.0, באפשרות הזו מוצג סימן X מעל לרכיב שכרגע יש לו להתמקד.
בנוסף, כל הרכיבים של סרגל הכלים ב-Android 8.0 עוברים באופן אוטומטי אשכולות של ניווט במקלדת, ולהקל על המשתמשים לנווט לתוך כל סרגל כלים ולצאת ממנו, כולו.
לקבלת מידע נוסף על שיפור התמיכה בניווט באמצעות המקלדת בתוך את האפליקציה שלכם, קראו את המאמר תמיכה מדריך ניווט במקלדת.
מילוי אוטומטי של טופס אינטרנט
עכשיו, באמצעות המילוי האוטומטי של Android
Framework מספק תמיכה מובנית לפונקציונליות של מילוי אוטומטי,
השיטות הבאות הקשורות ל-WebView
אובייקטים השתנו
לאפליקציות שמותקנות במכשירים עם Android 8.0 (רמת API 26):
WebSettings
-
-
getSaveFormData()
השיטה מחזירה את הערךfalse
. בעבר, השיטה הזו החזירה יש גם אפשרותtrue
. - ביצוע שיחה
setSaveFormData()
לא למשך זמן ארוך יותר.
-
WebViewDatabase
-
- ביצוע שיחה
clearFormData()
לא למשך זמן ארוך יותר. -
אמצעי תשלום אחד (
hasFormData()
) עכשיו מחזירהfalse
. בעבר, השיטה הזו החזירהtrue
כאשר הטופס הכיל נתונים.
- ביצוע שיחה
נגישות
Android 8.0 (רמת API 26) כולל את השינויים הבאים בנגישות:
-
במסגרת הנגישות, כל התנועות של הקשה כפולה ממירה עכשיו את כל התנועות של ההקשה הכפולה
ACTION_CLICK
פעולות. השינוי הזה מאפשר ל-TalkBack להתנהג יותר כמו תגובות אחרות שירותי נגישות.אם ב-
View
האובייקטים של האפליקציה נעשה שימוש במגע בהתאמה אישית עליך לוודא שהן עדיין פועלות עם TalkBack. ייתכן ש צריך רק לרשום את מטפל הקליקים ש-View
שבהם משתמשים. אם TalkBack עדיין לא מזהה תנועות שבוצעו בהןView
אובייקטים, שינוי מברירת המחדלperformAccessibilityAction()
. - שירותי הנגישות מודעים כעת לכל
ClickableSpan
מופעים בתוך האפליקציהTextView
אובייקטים.
כדי לקבל מידע נוסף על שיפור הנגישות של האפליקציה, אפשר לבקר בכתובת נגישות.
רשת וקישוריות HTTP(S)
Android 8.0 (רמת API 26) כולל את שינויי ההתנהגות הבאים ב: רשת וקישוריות HTTP(S):
- לבקשות אפשרויות ללא גוף יש
Content-Length: 0
הכותרת. בעבר לא הייתה להם כותרתContent-Length
. - הפונקציה HttpURLConnection מנרמלת כתובות URL שמכילות נתיבים ריקים על ידי צירוף
קו נטוי אחרי שם המארח או הרשות. לדוגמה,
ממירה את
http://example.com
ל-http://example.com/
. - בורר מותאם אישית של שרת proxy המוגדר באמצעות ProxySelector.setDefault() מטרגט רק את הכתובת (סכימה, מארח ויציאה) של כתובת URL מבוקשת. כתוצאה מכך, ייתכן שבחירת שרת proxy תתבסס רק על הערכים האלה. כתובת URL מועבר לבורר של שרת proxy מותאם אישית לא כולל את כתובות ה-URL המבוקשות נתיב, פרמטרים של שאילתה או מקטעים.
- מזהי URI לא יכולים להכיל תוויות ריקות.
בעבר, הפלטפורמה תמכה בפתרון עקיף לקבלת תוויות ריקות שמות מארחים, שהם שימוש לא חוקי ב-URI. הפתרון הזה נועד ל תאימות לגרסאות ישנות יותר של libcore. מפתחים שמשתמשים ב-API יראה באופן שגוי הודעת ADB: "URI example.com כולל תוויות ריקות ב- שם המארח. הפורמט הזה שגוי ולא יתקבל בעתיד ב-Android ". מערכת Android 8.0 מסירה את המעקף הזה. המערכת מחזירה null למזהי URI שגויים.
- יישום HttpsURLConnection ב-Android 8.0 לא משתמשת בגרסה לא מאובטחת של TLS/פרוטוקול SSL.
- הטיפול במנהור חיבורי HTTP(S) השתנה באופן הבא:
- בעת מנהור של חיבור HTTPS דרך חיבור, המערכת ממקמת בצורה נכונה את מספר היציאה (443) בשורת המארח בעת השליחה את המידע הזה לשרת ביניים. בעבר, השקע המספר התרחש רק בשורה CONNECT.
- המערכת לא שולחת יותר סוכן משתמש או הרשאה לשרת proxy
מבקשה במנהורת לשרת ה-proxy.
המערכת לא שולחת יותר כותרת להרשאת שרת proxy Http(s)URLConnection לשרת ה-proxy בעת הגדרת מנהרה. במקום זאת, המערכת יוצרת כותרת להרשאת שרת proxy, ושולח אותו לשרת ה-Proxy כששרת ה-Proxy שולח HTTP 407 בתגובה לבקשה הראשונית.
באופן דומה, המערכת לא מעתיקה יותר את הכותרת של סוכן המשתמש מהבקשה עם המנהור לבקשה של שרת ה-proxy שמגדירה מנהרה. במקום זאת, הספרייה יוצרת כותרת User-agent עבורה בקשה.
send(java.net.DatagramPacket)
ה-method מזרקת Socket מפרסמים אם ה-connect() שבוצע קודם לכן נכשלה.- DatagramSocket.connect() מגדיר ערך pendingSocketError אם יש שגיאה פנימית. לפני Android 8.0, הפונקציה recv() עוקבת הקריאה זרמה SocketError למרות שקריאה send() הייתה מצליחה. כדי לשמור על עקביות, שתי הקריאות גורמות עכשיו ל-SocketError.
- InetAddress.isReachable() מנסה את מערכת ה-ICMP לפני חזרה להד TCP
של Google.
- חלק מהמארחים שחוסמים את יציאה 7 (TCP Echo), כמו google.com, עשויים עכשיו יהיו נגישים אם הם מקבלים את פרוטוקול ICMP Echo.
- למארחים שלא ניתן להגיע אליהם באמת, השינוי הזה פירושו שסכום כפול הזמן שחולף לפני שהשיחה חוזרת.
Bluetooth
מערכת Android 8.0 (רמת API 26) מבצעת את השינויים הבאים באורך של
את הנתונים שהמודל ScanRecord.getBytes()
ה-method מאחזרת:
- השיטה
getBytes()
לא מניחה הנחות מספר הבייטים שהתקבלו. מהסיבה הזו, אפליקציות לא צריכות להסתמך על המספר המינימלי או המקסימלי של הבייטים שהוחזרו. במקום זאת, אורך המערך שמתקבל. - מכשירים שתואמים ל-Bluetooth 5 עשויים להחזיר נתונים שחורגים מאורך בערך הקודם, בערך 60 בייטים.
- אם מכשיר מרוחק לא מספק תגובת סריקה, פחות מ-60 בייטים עשויות להיות מוחזרות גם כן.
קישוריות חלקה
ב-Android 8.0 (רמת API 26) מתבצעים כמה שיפורים בהגדרות ה-Wi-Fi כדי להקל על הבחירה רשת ה-Wi-Fi שמציעה את חוויית המשתמש הטובה ביותר. השינויים הספציפיים כוללים:
- שיפורים ביציבות ובאמינות.
- ממשק משתמש קריא יותר באופן אינטואיטיבי.
- תפריט יחיד ומאוחד של העדפות Wi-Fi.
- במכשירים תואמים, הפעלה אוטומטית של Wi-Fi כאשר רשת שמורה באיכות גבוהה בקרבת מקום.
אבטחה
מערכת Android 8.0 כוללת את הרכיבים הבאים הקשורים לאבטחה שינויים:
- הפלטפורמה לא תומכת יותר ב-SSLv3.
- כשיוצרים חיבור HTTPS לשרת,
משתמשת במשא ומתן בגרסת פרוטוקול של TLS,
HttpsURLConnection
לא מנסה יותר לפתור את הבעיה של חזרה לגרסאות קודמות של פרוטוקול TLS וביצוע ניסיון חוזר. - מערכת Android 8.0 (רמת API 26) מחילה מחשוב מאובטח (SECCOMP) סינון לפי כל האפליקציות. רשימת ה-syscalls המותרים מוגבלת למפרסמים נחשףות דרך יונית. למרות שיש כמה מערכות קריאה אחרות לתאימות לאחור, אנחנו ממליצים לא להשתמש בהם.
WebView
האובייקטים של האפליקציה פועלים עכשיו בריבוי תהליכים במצב תצוגה. תוכן מהאינטרנט מטופל בתהליך נפרד ומבודד שכולל את התהליך של האפליקציה לאבטחה משופרת.-
כבר לא ניתן להניח שחבילות APK נמצאות בספריות שהשמות שלהן מסתיימים
ב-1 או ב-2. באילו אפליקציות צריך להשתמש
sourceDir
כדי לקבל את ההטבה ולא להסתמך ישירות על פורמט הספרייה. - למידע על שיפורי אבטחה שקשורים לשימוש בשפת נייטיב ספריות, ראו ספריות מקוריות.
בנוסף, בגרסה Android 8.0 (רמת API 26) מוצגים השינויים הבאים שקשורים להתקנה אפליקציות לא מוכרות ממקורות לא מוכרים:
- הערך של ההגדרה הקודמת
INSTALL_NON_MARKET_APPS
נקראת עכשיו תמיד 1. כדי לקבוע אם מקור לא ידוע יכול להתקין אפליקציות באמצעות עליך להשתמש במקום זאת בערך המוחזר שלcanRequestPackageInstalls()
- אם מנסים לשנות את הערך של
INSTALL_NON_MARKET_APPS
משתמשיםsetSecureSetting()
,UnsupportedOperationException
נזרק. כדי למנוע ממשתמשים להתקין אפליקציות לא מוכרות באמצעות אפליקציות לא מוכרות מקורות מידע, צריך להחיל במקום זאת משתמש ב-DISALLOW_INSTALL_UNKNOWN_SOURCES
המוגבלות של המשאבים. -
לפרופילים מנוהלים שנוצרו במכשירים עם Android 8.0 (API ברמה 26), מוגדר באופן אוטומטי
משתמש ב-
DISALLOW_INSTALL_UNKNOWN_SOURCES
ההגבלה מופעלת. לפרופילים מנוהלים קיימים במכשירים ששודרגו ל-Android 8.0, משתמש ב-DISALLOW_INSTALL_UNKNOWN_SOURCES
ההגבלה מופעלת באופן אוטומטי, אלא אם הבעלים של הפרופיל הגדיר במפורש השביתה את ההגבלה הזו (לפני השדרוג) באמצעות הגדרהINSTALL_NON_MARKET_APPS
ל-1.
לקבלת פרטים נוספים על התקנת אפליקציות לא מוכרות, אפשר לעיין ב אפליקציה לא ידועה התקנת ההרשאות.
הנחיות נוספות לשיפור האבטחה באפליקציה זמינות במאמר אבטחה למפתחי Android.
פרטיות
בגרסת Android 8.0 (רמת API 26) מתבצעת את הפעולות הבאות שקשורות לפרטיות לשינויים בפלטפורמה.
- הפלטפורמה הזו מטפלת עכשיו במזהים באופן שונה.
-
עבור אפליקציות שהותקנו לפני OTA לגרסה של
Android 8.0 (רמת API 26)
(רמת API 26), הערך של
המדד
ANDROID_ID
לא השתנה אלא אם הם הוסרו ואז הותקנו מחדש לאחר ה-OTA. כדי לשמור על ערכים בכל הסרות לאחר OTA, מפתחים יכולים לשייך את הערכים הישנים לערכים החדשים באמצעות גיבוי של מפתחות/ערך. - עבור אפליקציות שמותקנות במכשיר שמותקנת בו מערכת Android 8.0, הערך
ANDROID_ID
בהיקף לכל חתימת אפליקציה, וגם לכל משתמש. הערך שלANDROID_ID
הוא ייחודי לכל שילוב של חתימת אפליקציה, משתמש ומכשיר. כתוצאה מכך, אפליקציות עם מפתחות חתימה שונים פועלות באותו מכשיר לא לראות יותר את אותו מזהה Android (גם לא עבור אותו משתמש). - הערך של
ANDROID_ID
לא משתנה בהסרה או בהתקנה מחדש של החבילה, כל עוד מפתח החתימה זהה (והאפליקציה לא הותקנה לפני OTA ל- גרסה 8.0 של Android). - הערך של
ANDROID_ID
לא משתנה גם אם עדכון מערכת גורם לשינוי מפתח חתימת החבילה. - במכשירים עם מזהה הפרסום ומזהה הפרסום של Google Play Services,
חובה להשתמש
מזהה הפרסום. מערכת פשוטה וסטנדרטית למונטיזציה מאפליקציות.
מזהה פרסום הוא מזהה ייחודי שניתן לאיפוס על ידי המשתמש לצורך פרסום. כן,
מאת Google Play Services.
מומלץ להמשיך עם יצרני מכשירים אחרים כדי לספק
ANDROID_ID
.
-
עבור אפליקציות שהותקנו לפני OTA לגרסה של
Android 8.0 (רמת API 26)
(רמת API 26), הערך של
המדד
- שליחת שאילתה למאפיין המערכת
net.hostname
מחזירה ערך null תוצאה אחת.
רישום של חריגות שלא זוהו
אם אפליקציה מתקינה Thread.UncaughtExceptionHandler
לא לקרוא לברירת המחדל Thread.UncaughtExceptionHandler
,
שהמערכת עושה
לא להרוג את האפליקציה כשמתרחש חריג לא מובן. החל מ-
Android 8.0 (רמת API 26), המערכת רושמת ביומן את דוח הקריסות החריג
מצב; בגרסאות קודמות של הפלטפורמה, המערכת לא הייתה
תועד דוח הקריסות של החריגים.
מומלץ להתאים אישית את Thread.UncaughtExceptionHandler
של הטמעות, תמיד צריך לקרוא
ה-handler שמוגדר כברירת מחדל; אפליקציות שמבוססות על ההמלצה הזו לא מושפעות
השינוי ב-Android 8.0.
שינוי בחתימה של findViewById()
כל המופעים של השיטה findViewById()
מחזירים עכשיו את הערך
<T extends View> T
במקום View
. השינוי הזה
יש את ההשלכות הבאות:
- כתוצאה מכך, יכול להיות שסוג ההחזרה לא ברור לקוד הקיים,
לדוגמה אם יש גם
someMethod(View)
וגםsomeMethod(TextView)
שמעביר את התוצאה של הקריאה אלfindViewById()
. - כשמשתמשים בשפת המקור של Java 8, צריך להפעיל Cast מפורש אל
View
כשסוג ההחזרה לא מוגבל (לדוגמה,assertNotNull(findViewById(...)).someViewMethod())
. - שינויים של
findViewById()
methods שאינן סופיות (עבור לדוגמה,Activity.findViewById()
) יצטרך להחזיר את המוצר הסוג עודכן.
שינוי בנתוני השימוש של ספק אנשי הקשר
בגרסאות קודמות של Android, הרכיב 'ספק אנשי קשר'
מאפשרת למפתחים לקבל נתוני שימוש לכל איש קשר. נתוני השימוש האלה
חושף מידע על כל כתובת אימייל ועל כל מספר טלפון שמשויך אליה
עם איש קשר, כולל מספר הפעמים שיצרו איתו קשר
ואת הפעם האחרונה שבה נוצר קשר עם איש הקשר. אפליקציות שמבקשות את
READ_CONTACTS
הרשאה לקרוא את הנתונים האלה.
אפליקציות עדיין יכולות לקרוא את הנתונים האלה אם הן מבקשות
READ_CONTACTS
הרשאה. בגרסה Android 8.0 (רמת API 26) ואילך, שאילתות לגבי נתוני שימוש מוחזרות
הם אומדנים ולא ערכים מדויקים. מערכת Android שומרת על
באופן פנימי, לכן השינוי הזה לא משפיע על
להשלמה אוטומטית של ממשקי API.
השינוי הזה בהתנהגות משפיע על הפרמטרים הבאים של השאילתות:
טיפול באוסף
AbstractCollection.removeAll()
ו-AbstractCollection.retainAll()
עכשיו תן תמיד NullPointerException
; קודם,
NullPointerException
לא שודר כשהאוסף
ריק. השינוי הזה מבטיח שההתנהגות תהיה תואמת למסמכי התיעוד.
Android לארגונים
מערכת Android 8.0 (רמת API 26) משנה את ההתנהגות של חלק מממשקי ה-API והתכונות באפליקציות לארגונים, כולל מכשירים נאמני מידע (DPC). השינויים כוללים:
- פונקציות חדשות שיעזרו לאפליקציות לתמוך בפרופילי עבודה במכשירים מנוהלים.
- שינויים בטיפול בעדכוני המערכת, באימות אפליקציות ובאימות לצורך לשפר את תקינות המכשיר והמערכת.
- שיפורים בחוויית המשתמש עבור הקצאה, התראות, מסך מהזמן האחרון ו-VPN שפועל כל הזמן.
כדי לראות את כל השינויים הארגוניים ב-Android 8.0 (רמת API 26) וללמוד כיצד הם עשויים להיות זמינים משפיעים על האפליקציה, קוראים את Android ב-Enterprise.
אפליקציות שמטרגטות את Android 8.0
השינויים האלה בהתנהגות חלים רק על אפליקציות שמטרגטות
Android מגרסה 8.0 (רמת API 26) ואילך. אפליקציות שעברו הידור (compile) ל-Android 8.0,
או להגדיר את targetSdkVersion
ל-Android 8.0 ואילך חייבים לשנות
את האפליקציות שלהם כך שיתמכו בהתנהגויות האלה באופן תקין, במקרים שבהם הן רלוונטיות.
חלונות התראות
אפליקציות שמשתמשות בהרשאה SYSTEM_ALERT_WINDOW
לא תהיה יותר אפשרות להשתמש בסוגי החלונות הבאים כדי להציג חלונות התראות
מעל אפליקציות אחרות וחלונות מערכת:
במקום זאת, האפליקציות חייבות להשתמש בסוג חלון חדש שנקרא
TYPE_APPLICATION_OVERLAY
כשמשתמשים באופרטור
חלון TYPE_APPLICATION_OVERLAY
מקלידים כדי להציג חלונות התראות עבור האפליקציה, שומרים את המאפיינים הבאים
של סוג החלון החדש:
- חלונות ההתראות של האפליקציה תמיד מופיעים מתחת לחלונות מערכת חיוניים, כמו כשורת הסטטוס ו-IMEs.
- המערכת יכולה להזיז או לשנות את הגודל של חלונות שמשתמשים ב-
TYPE_APPLICATION_OVERLAY
סוג החלון כדי לשפר את תצוגת המסך. - על ידי פתיחת לוח ההתראות, משתמשים יכולים לגשת להגדרות של חסימה
מהצגת חלונות התראות שמוצגים באמצעות
TYPE_APPLICATION_OVERLAY
סוג החלון.
התראות על שינויים בתוכן
מערכת Android 8.0 (רמת API 26) משנה את האופן שבו
ContentResolver.notifyChange()
ו-registerContentObserver(Uri, boolean, ContentObserver)
להתנהג באפליקציות שמטרגטות את Android 8.0.
מעכשיו, ממשקי ה-API האלה נדרשים לספק ContentProvider
חוקי
מוגדר עבור הרשות בכל Uris. הגדרת ContentProvider
תקין עם ההרשאות הרלוונטיות
עוזרות להגן על האפליקציה שלך מפני שינויי תוכן מפני אפליקציות זדוניות, ולמנוע ממך
הדלפה של מידע פרטי שעשוי להיות פרטי לאפליקציות זדוניות.
הצגת המיקוד
אובייקטים מסוג View
שניתן ללחוץ עליהם עכשיו ניתנים למיקוד גם באמצעות
כברירת מחדל. אם רוצים שאובייקט View
יהיה קליקבילי, אבל לא
שניתן להתמקד בו,
מאפיין android:focusable
ל-false
בפריסה
קובץ XML שמכיל את View
, או מעביר ב-false
אל setFocusable()
בממשק המשתמש של האפליקציה
בלוגיקה.
התאמת סוכן משתמש בזיהוי הדפדפן
Android 8.0 (רמת API 26) ואילך כולל את
מחרוזת מזהה ה-build OPR
. התאמות מסוימות של הדפוסים עשויות
תגרום ללוגיקת זיהוי הדפדפן לזהות בטעות דפדפן שאינו Opera כ-Opera.
דוגמה להתאמת תבניות כזו יכולה להיות:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
כדי להימנע מבעיות שנובעות מזיהוי שגוי כזה, צריך להשתמש במחרוזת שאינה
OPR
כהתאמה לדפוס בדפדפן Opera.
אבטחה
השינויים הבאים משפיעים על האבטחה ב-Android 8.0 (רמת API 26):
- אם ההגדרות של אבטחת הרשת באפליקציה
אפשרויות
את התמיכה בתנועת טקסט ללא הצפנה,
אובייקטים מסוג
WebView
לא יכולים לגשת לאתרים באמצעות HTTP. כל אחד במקום זאת, אובייקטWebView
חייב להשתמש ב-HTTPS. - הגדרת המערכת התרת מקורות לא מוכרים הוסרה. כחלק במקום, ההרשאה התקנת אפליקציות לא מוכרות מנהלת התקנות של אפליקציות לא מוכרות ממקורות לא ידועים. מידע נוסף על ההרשאה החדשה הזו זמין ב אפליקציה לא ידועה התקנת ההרשאות.
הנחיות נוספות לשיפור האבטחה באפליקציה זמינות במאמר אבטחה למפתחי Android.
גישה לחשבון ויכולת גילוי
ב-Android 8.0 (רמת API 26) אין יותר גישה לאפליקציות
לחשבונות משתמשים, אלא אם המאמת הוא הבעלים של החשבונות או
משתמש מעניק את הרשאת הגישה הזו.
הרשאה מסוג GET_ACCOUNTS
כבר לא מספיק. כדי לקבל גישה לחשבון, אפליקציות
צריך להשתמש ב-AccountManager.newChooseAccountIntent()
או נתונים ספציפיים למאמת החשבונות
. לאחר קבלת גישה לחשבונות, אפליקציה יכולה להתקשר
AccountManager.getAccounts()
כדי לגשת אליהן.
Android 8.0 יוצא משימוש
LOGIN_ACCOUNTS_CHANGED_ACTION
קמפיינים לקידום אפליקציות
צריך להשתמש במקום זאת
addOnAccountsUpdatedListener()
כדי לקבל עדכונים לגבי חשבונות במהלך זמן ריצה.
לקבלת מידע על שיטות וממשקי API חדשים שנוספו לגישה לחשבון ועל יכולת גילוי, ראה גישה לחשבון ו-Discover בקטע New APIs (ממשקי API חדשים) במסמך זה.
פרטיות
השינויים הבאים משפיעים על הפרטיות ב-Android 8.0 (רמת API 26).
-
מאפייני המערכת:
net.dns1
,net.dns2
,net.dns3
ו-net.dns4
כבר לא זמין, שינוי שמשפר את הפרטיות בפלטפורמה. -
כדי לקבל מידע על רשתות, כמו שרתי DNS, אפליקציות עם
ACCESS_NETWORK_STATE
הרשאה יכולה לרשוםNetworkRequest
או אובייקטNetworkCallback
. הכיתות האלה זמינות ב-Android מגרסה 5.0 (רמת API 21) ואילך. -
Build.SERIAL הוצא משימוש.
במקום זאת, אפליקציות שצריכות לדעת את המספר הסידורי של החומרה
להשתמש בשיטה
Build.getSerial()
החדשה, דורשREAD_PHONE_STATE
הרשאה. -
באמצעות API של
LauncherApps
אי אפשר יותר ליצור פרופיל עבודה כדי לקבל מידע על הפרופיל הראשי. כשמשתמש נמצא בעבודה הפרופיל, ה-API שלLauncherApps
פועל כאילו אין אפליקציות מותקנים בפרופילים אחרים באותה קבוצת פרופילים. כמו קודם, ניסיונות לגשת לפרופילים לא קשורים גורמים ל-Security חריגות.
הרשאות
לפני Android 8.0 (רמת API 26), אם אפליקציה ביקשה הרשאה בזמן הריצה וההרשאה ניתנה, המערכת גם העניק לאפליקציה את שאר ההרשאות ששייכות לאותה אפליקציה קבוצת הרשאות שנרשמו במניפסט.
באפליקציות שמטרגטות ל-Android 8.0, ההתנהגות הזו תוקן. האפליקציה מקבלת רק את ההרשאות שהיא קיבלה באופן מפורש נדרש. עם זאת, ברגע שהמשתמש מעניק הרשאה לאפליקציה, כל הבקשות הבאות להרשאות בקבוצת ההרשאות הזו הוענקה אוטומטית.
לדוגמה, נניח שאפליקציה מציגה גם את READ_EXTERNAL_STORAGE
וגם
WRITE_EXTERNAL_STORAGE
במניפסט שלו.
האפליקציה מבקשת READ_EXTERNAL_STORAGE
וגם
שהמשתמש מעניק לו. אם האפליקציה מטרגטת רמת API 25 ומטה, המערכת גם
מעניקה WRITE_EXTERNAL_STORAGE
במספר זהה
כי הוא שייך לאותה קבוצת הרשאות STORAGE
וגם
רשומות במניפסט. אם האפליקציה מטרגטת את Android 8.0 (רמת API 26), המערכת מעניקה
רק READ_EXTERNAL_STORAGE
באותו זמן;
עם זאת, אם האפליקציה תבקש את WRITE_EXTERNAL_STORAGE
בשלב מאוחר יותר, המערכת מיד
מעניקה את ההרשאה הזו בלי להציג בקשה למשתמש.
מדיה
- תוכנת ה-framework יכולה לבצע
הנמכה אוטומטית של עוצמת השמע
כשלעצמו. במקרה הזה, כשאפליקציה אחרת מתמקדת ב-
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
, האפליקציה בעל התמקדות מפחית את עוצמת הקול שלו, אבל בדרך כלל לא מקבלonAudioFocusChange()
להתקשרות חזרה ולא פוקוס האודיו. יש ממשקי API חדשים כדי לבטל את ההתנהגות הזו עבור שצריך להשהות במקום להנמיך אותם. - כשהמשתמש מבצע שיחת טלפון, שידורי המדיה הפעילים מושתקים למשך שיחה.
- כל ממשקי ה-API שקשורים לאודיו צריכים להשתמש ב-
AudioAttributes
במקום סוגים של זרם אודיו כדי לתאר את התרחיש לדוגמה של הפעלת אודיו. ממשיכים להשתמש בסוגים של שידורי אודיו רק לבקרת עוצמת הקול. שימושים אחרים בסוגי מקורות נתונים ימשיכו לפעול (לדוגמה, הארגומנטstreamType
לתג שהוצאה משימושAudioTrack
constructor), אבל המערכת מתעדת את הפעולה הזו כשגיאה. - כשמשתמשים ב-
AudioTrack
, אם האפליקציה מבקש מאגר אודיו גדול מספיק, המערכת תנסה להשתמש בפלט של מאגר הנתונים הזמני העמוק, אם הוא זמין. - ב-Android 8.0 (רמת API 26) אופן הטיפול באירועים של לחצני מדיה שונה:
- אופן הטיפול בלחצני המדיה בפעילות בממשק המשתמש לא השתנה: פעילויות בחזית עדיין מקבלות עדיפות בטיפול אירועים של לחצן מדיה.
- אם הפעילות בחזית לא מטפלת באירוע של לחצן המדיה, המערכת מנתבת את האירוע לאפליקציה שהשמיעה לאחרונה אודיו באופן מקומי. סטטוס פעיל, דגלים והפעלה המצב של סשן במדיה אינו מובאים בחשבון בעת קביעה איזו אפליקציה מקבלת מדיה אירועי לחצנים.
- אם שוחררו סשן המדיה של האפליקציה,
המערכת שולחת את האירוע של לחצן המדיה
MediaButtonReceiver
אם יש לו. - בכל מקרה אחר, המערכת מוחקת את האירוע של לחצן המדיה.
ספריות מקוריות
באפליקציות שמטרגטות ל-Android 8.0 (רמת API 26), ספריות מקוריות לא טעינה ארוכה יותר אם הם מכילים קטע עומס שהוא גם ניתן לכתיבה קובץ הפעלה. יכול להיות שאפליקציות מסוימות יפסיקו לפעול בגלל השינוי הזה, אם הן ספריות מקוריות עם מקטעי טעינה שגויים. זהו אמצעי לחיזוק האבטחה.
מידע נוסף זמין במאמר פלחים ניתנים לכתיבה ולביצוע.
שינויים ב-Linker קשורים לרמת ה-API שהאפליקציה מטרגטת. אם יש הוא שינוי מקשר ברמת ה-API המטורגטת, האפליקציה לא יכולה לטעון את הספרייה. אם אתם מטרגטים רמת API נמוכה מרמת ה-API שבה מתרחש השינוי המקשר, Logcat מציג אזהרה.
טיפול באוסף
ב-Android 8.0 (רמת API 26),
ההטמעה של Collections.sort()
בוצעה בתאריך
בחלק העליון של List.sort()
. להיפך
היה True ב-Android 7.x (רמות API 24 ו-25):
הטמעת ברירת המחדל של List.sort()
שנקרא Collections.sort()
.
השינוי הזה מאפשר ל-Collections.sort()
כדי לנצל את האופטימיזציה של List.sort()
אלא על המגבלות הבאות:
הטמעות של
List.sort()
לא יכול לקרוא ל-Collections.sort()
, כי הפעולה הזו תגרום להצגת גלישת קריסות בגלל חזרה אינסופית. במקום זאת, אם רוצים להגדיר את התנהגות ברירת המחדל בהטמעה שלList
, צריך להימנע מעקיפתsort()
.אם כיתת הורה מטמיעה את
sort()
באופן לא הולם, בדרך כלל אפשר לעקוף אתList.sort()
באמצעות הטמעה שמבוססת עלList.toArray()
,Arrays.sort()
, וגםListIterator.set()
לדוגמה:@Override public void sort(Comparator<? super E> c) { Object[] elements = toArray(); Arrays.sort(elements, c); ListIterator<E> iterator = (ListIterator<Object>) listIterator(); for (Object element : elements) { iterator.next(); iterator.set((E) element); } }
ברוב המקרים אפשר גם לשנות מברירת המחדל
List.sort()
עם שמשתמשת במודלים שונים של ברירת מחדל בהתאם לרמת ה-API. לדוגמה:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
אם בוחרים באפשרות השנייה רק כי רוצים
sort()
הזמינה בכל רמות ה-API, כדאי לתת לה שם ייחודי, כמוsortCompat()
, במקום לשנותsort()
-
Collections.sort()
נחשב עכשיו בתור שינוי מבני הצגת רשימה של הטמעות שקריאות ל-sort()
. לדוגמה, בגרסאות של בפלטפורמה שקודמת ל-Android 8.0 (רמת API 26), חזרה עלArrayList
והתקשרות אליוsort()
דרך האיטרציה היה מחזירConcurrentModificationException
אם המיון בוצע באמצעות הטלפוןList.sort()
.Collections.sort()
לא גרמה לחריגה.השינוי הזה נועד להגביר את העקביות של אופן הפעולה של הפלטפורמה: גישה כזו תוביל עכשיו ל-
ConcurrentModificationException
.
ההתנהגות של טעינת הכיתה
Android 8.0 (רמת API 26) מבצע בדיקה כדי לוודא שמרכזי הטעינה של מחלקות לא
לשבור את ההנחות לגבי סביבת זמן הריצה כשטוענים מחלקות חדשות. הבדיקות האלה
מבוצעת אם ההפניה למחלקה מ-Java (
forName()
),
בייטקוד Dalvik או JNI. הפלטפורמה לא מיירט שיחות ישירות מ-Java
שיטת loadClass()
, וגם לא בודקת אותה
התוצאות של שיחות כאלה. התנהגות כזו לא אמורה להשפיע על תפקוד תקין.
הטעינה של הכיתה.
הפלטפורמה בודקת שהמתאר של המחלקה שמחזיר את ה-class load
תואם למתאר הצפוי. אם המתאר שהוחזר לא תואם,
הפלטפורמה גורמת לשגיאה NoClassDefFoundError
ומאחסנת
הודעה מפורטת שמציינת את הפער.
הפלטפורמה גם בודקת שהמתארים של המחלקות המבוקשות תקפים. הזה
בודקות קריאות JNI שטוענים מחלקות באופן עקיף כמו GetFieldID()
,
העברת תיאורים לא חוקיים למחלקות האלה. לדוגמה, שדה עם חתימה
האפליקציה java/lang/String
לא נמצאה כי החתימה הזו לא חוקית.
הוא צריך להיות Ljava/lang/String;
.
שיחה זו שונה מקריאה של JNI ל-FindClass()
java/lang/String
הוא שם בעל הרשאות מלאות.
ב-Android 8.0 (רמת API 26) אין תמיכה בכך שמטענים מרובים של מחלקות ינסו להגדיר מחלקות
באמצעות אותו אובייקט DexFile. ניסיון לעשות זאת יגרום לסביבת זמן הריצה של Android
InternalError
עם ההודעה "ניסיון לרשום קובץ dex" <filename>
עם כמה טעינה של כיתות".
DexFile API הוצא משימוש, ומומלץ מאוד להשתמש בו
אחד מה-classloads של הפלטפורמה, כולל PathClassLoader
או
BaseDexClassLoader
, במקום זאת.
הערה: אפשר ליצור כמה טעינות של כיתות שמפנות אל
אותו APK או מאגר קבצים JAR ממערכת הקבצים. בדרך כלל אי אפשר לעשות את זה
עלולות לגרום לתקורת זיכרון גדולה: אם קובצי DEX בקונטיינר מאוחסנים במקום
דחוסה, הפלטפורמה יכולה לבצע פעולת mmap
במקום
כדי לחלץ אותן ישירות. עם זאת, אם הפלטפורמה חייבת לחלץ את קובץ ה-DEX מהמאגר,
הפניה לקובץ DEX באופן הזה עשויה לצרוך זיכרון רב.
ב-Android, כל מטעני הכיתות נחשבים לבעלי יכולת מקבילה. כשכמה שרשורים מתחרים לטעינת אותה כיתה באותה כיתה בטעינה, ה-thread הראשון שמשלים את הפעולה מנצח, והתוצאה משמשת השרשורים האחרים. אופן הפעולה הזה מתרחש בלי קשר לטעינת המחלקה החזירו את אותו כיתה, החזירו מחלקה אחרת או השלימו חריגה. המערכת מתעלמת מחריגות כאלה בלי להציג אזהרה או שגיאה.
זהירות: בגרסאות של הפלטפורמה נמוכה מ-Android 8.0 (רמת API 26), הפרה של ההנחות האלה יכולה להוביל להגדרת הרבה פעמים, ערימה של שחיתות בגלל בלבול בכיתה, והשפעות לא רצויות אחרות.