פלטפורמת Android 16 כוללת שינויים בהתנהגות שעשויים להשפיע על האפליקציה שלכם. שינויי ההתנהגות הבאים חלים על כל האפליקציות כשהן פועלות ב-Android 16, בלי קשר ל-targetSdkVersion. מומלץ לבדוק את האפליקציה ולשנות אותה לפי הצורך כדי לתמוך בשינויים האלה, במקרים הרלוונטיים.
חשוב גם לעיין ברשימת השינויים בהתנהגות שמשפיעים רק על אפליקציות שמטרגטות ל-Android 16.
פונקציונליות עיקרית
Android 16 (API ברמה 36) כוללת את השינויים הבאים, שמשנים או מרחיבים יכולות ליבה שונות של מערכת Android.
אופטימיזציות של מכסות ב-JobScheduler
Starting in Android 16, we're adjusting regular and expedited job execution runtime quota based on the following factors:
- Which app standby bucket the application is in: in Android 16, active standby buckets will start being enforced by a generous runtime quota.
- If the job starts execution while the app is in a top state: in Android 16, Jobs started while the app is visible to the user and continues after the app becomes invisible, will adhere to the job runtime quota.
- If the job is executing while running a Foreground Service: in Android 16, jobs that are executing concurrently with a foreground service will adhere to the job runtime quota. If you're leveraging jobs for user initiated data transfer, consider using user initiated data transfer jobs instead.
This change impacts tasks scheduled using WorkManager, JobScheduler, and
DownloadManager. To debug why a job was stopped, we recommend logging why your
job was stopped by calling WorkInfo.getStopReason() (for
JobScheduler jobs, call JobParameters.getStopReason()).
For information about how your app's state affects the resources it can use, see Power management resource limits. For more information on battery-optimal best practices, refer to guidance on optimize battery use for task scheduling APIs.
We also recommend leveraging the new
JobScheduler#getPendingJobReasonsHistory API introduced in
Android 16 to understand why a job has not executed.
Testing
To test your app's behavior, you can enable override of certain job quota optimizations as long as the app is running on an Android 16 device.
To disable enforcement of "top state will adhere to job runtime quota", run the
following adb command:
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS APP_PACKAGE_NAME
To disable enforcement of "jobs that are executing while concurrently with a
foreground service will adhere to the job runtime quota", run the following
adb command:
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS APP_PACKAGE_NAME
To test certain app standby bucket behavior, you can set the app standby bucket
of your app using the following adb command:
adb shell am set-standby-bucket APP_PACKAGE_NAME active|working_set|frequent|rare|restricted
To understand the app standby bucket your app is in, you can get the app standby
bucket of your app using the following adb command:
adb shell am get-standby-bucket APP_PACKAGE_NAME
הסיבה להפסקת עבודות ריקות שננטשו
An abandoned job occurs when the JobParameters object associated with the job
has been garbage collected, but JobService#jobFinished(JobParameters,
boolean) has not been called to signal job completion. This indicates that
the job may be running and being rescheduled without the app's awareness.
Apps that rely on JobScheduler, don't maintain a strong reference to the
JobParameters object, and timeout will now be granted the new job stop reason
STOP_REASON_TIMEOUT_ABANDONED, instead of STOP_REASON_TIMEOUT.
If there are frequent occurrences of the new abandoned stop reason, the system will take mitigation steps to reduce job frequency.
Apps should use the new stop reason to detect and reduce abandoned jobs.
If you're using WorkManager, AsyncTask, or DownloadManager, you aren't impacted because these APIs manage the job lifecycle on your app's behalf.
הוצאה מלאה משימוש של JobInfo#setImportantWhileForeground
JobInfo.Builder#setImportantWhileForeground(boolean) 方法用于在调度应用位于前台或暂时豁免于后台限制时指示作业的优先级。
自 Android 12(API 级别 31)起,此方法已废弃。从 Android 16 开始,它不再有效,系统会忽略调用此方法。
此功能移除也适用于 JobInfo#isImportantWhileForeground()。从 Android 16 开始,如果调用该方法,该方法会返回 false。
ההיקף של סדר העדיפויות של שידורים כבר לא גלובלי
Android 应用可以为广播接收器定义优先级,以控制接收器接收和处理广播的顺序。对于清单声明的接收器,应用可以使用 android:priority 属性来定义优先级;对于上下文注册的接收器,应用可以使用 IntentFilter#setPriority() API 来定义优先级。发送广播时,系统会按接收器的优先级(从高到低)将其传送给接收器。
在 Android 16 中,无法保证使用 android:priority 属性或 IntentFilter#setPriority() 在不同进程中传送广播的顺序。广播优先级仅在同一应用进程内有效,而不会跨所有进程有效。
此外,广播优先级将自动限制在 (SYSTEM_LOW_PRIORITY + 1, SYSTEM_HIGH_PRIORITY - 1) 的范围内。只有系统组件才能将 SYSTEM_LOW_PRIORITY、SYSTEM_HIGH_PRIORITY 设置为广播优先级。
如果您的应用执行以下任一操作,可能会受到影响:
- 您的应用声明了具有相同广播 intent 的多个进程,并且希望根据优先级以特定顺序接收这些 intent。
- 您的应用进程与其他进程交互,并期望以特定顺序接收广播 intent。
如果进程需要相互协调,则应使用其他协调渠道进行通信。
שינויים פנימיים ב-ART
Android 16 כולל את העדכונים האחרונים ל-Android Runtime (ART), שמשפרים את הביצועים של Android Runtime (ART) ומספקים תמיכה בתכונות נוספות של Java. דרך עדכוני המערכת של Google Play, השיפורים האלה זמינים גם ליותר ממיליארד מכשירים עם Android 12 (רמת API 31) ואילך.
כשהשינויים האלה יפורסמו, יכול להיות שספריות וקוד של אפליקציות שמסתמכים על מבנים פנימיים של ART לא יפעלו כראוי במכשירים עם Android 16, וגם בגרסאות קודמות של Android שבהן מופעלים עדכוני מערכת של Google Play למודול ART.
תמיד יכולות להיות בעיות תאימות אם מסתמכים על מבנים פנימיים (כמו ממשקים שאינם SDK), אבל חשוב במיוחד להימנע מהסתמכות על קוד (או ספריות שמכילות קוד) שמשתמש במבנים פנימיים של ART, כי השינויים ב-ART לא קשורים לגרסה של הפלטפורמה שבה המכשיר פועל, והם מועברים ליותר ממיליארד מכשירים דרך עדכוני המערכת של Google Play.
כל המפתחים צריכים לבדוק אם האפליקציה שלהם מושפעת מהשינוי, על ידי בדיקה יסודית של האפליקציות ב-Android 16. בנוסף, כדאי לבדוק את הבעיות המוכרות כדי לראות אם האפליקציה שלכם תלויה בספריות שזיהינו שתלויה במבנים פנימיים של ART. אם יש לכם קוד אפליקציה או יחסי תלות בספרייה שמושפעים מהשינוי, כדאי לנסות למצוא חלופות לממשקי API ציבוריים כשהדבר אפשרי, ולבקש ממשקי API ציבוריים לתרחישי שימוש חדשים על ידי יצירת בקשה לתכונה באתר למעקב אחר בעיות.
מצב תאימות לגודל דף של 16KB
ב-Android 15 נוספה תמיכה בדפים בזיכרון בגודל 16KB כדי לייעל את הביצועים של הפלטפורמה. ב-Android 16 נוספה תמיכה במצב תאימות, שמאפשר לאפליקציות מסוימות שנוצרו לדפים בזיכרון בנפח 4KB לפעול במכשיר שמוגדר לדפים בזיכרון בנפח 16KB.
כשהאפליקציה פועלת במכשיר עם Android מגרסה 16 ואילך, אם מערכת Android מזהה שהאפליקציה כוללת דפי זיכרון בגודל 4KB, היא משתמשת באופן אוטומטי במצב תאימות ומציגה למשתמש תיבת דו-שיח עם התראה. הגדרת המאפיין android:pageSizeCompat בקובץ AndroidManifest.xml כדי להפעיל את מצב התאימות לאחור תמנע את הצגת תיבת הדו-שיח כשהאפליקציה מופעלת. כדי להשתמש בנכס android:pageSizeCompat, צריך לקמפל את האפליקציה באמצעות Android 16 SDK.
כדי לקבל את הביצועים, האמינות והיציבות הטובים ביותר, עדיין צריך לבצע התאמה של האפליקציה ל-16 KB. פרטים נוספים זמינים בפוסט האחרון שלנו בבלוג בנושא עדכון האפליקציות כך שיתמכו בדפי זיכרון בגודל 16KB.
חוויית המשתמש וממשק המשתמש של המערכת
Android 16 (API ברמה 36) כוללת את השינויים הבאים, שנועדו ליצור חוויית משתמש עקבית ואינטואיטיבית יותר.
הוצאה משימוש של הודעות נגישות מפריעות
ב-Android 16 הופסקה התמיכה בהודעות נגישות, שמתאפיינות בשימוש ב-announceForAccessibility או בשליחת אירועי נגישות מסוג TYPE_ANNOUNCEMENT. כתוצאה מכך, חוויית המשתמש של משתמשי TalkBack וקורא המסך של Android עשויה להיות לא עקבית. חלופות יכולות לעזור לטפל בטווח רחב יותר של צרכים של משתמשים במגוון טכנולוגיות העזרה של Android.
דוגמאות לחלופות:
- לשינויים משמעותיים בממשק המשתמש, כמו שינויים בחלונות, צריך להשתמש ב-
Activity.setTitle(CharSequence)וב-setAccessibilityPaneTitle(java.lang.CharSequence). ב-Compose, משתמשים ב-Modifier.semantics { paneTitle = "paneTitle" } - כדי להודיע למשתמש על שינויים בממשק המשתמש הקריטי, משתמשים ב-
setAccessibilityLiveRegion(int). בחלונית הכתיבה, משתמשים ב-Modifier.semantics { liveRegion = LiveRegionMode.[Polite|Assertive]}. מומלץ להשתמש בהם במשורה, כי הם עלולים ליצור הודעות בכל פעם שנתונים מתעדכנים בתצוגה. - כדי להודיע למשתמשים על שגיאות, שולחים
AccessibilityEventמסוגAccessibilityEvent#CONTENT_CHANGE_TYPE_ERRORומגדירים אתAccessibilityNodeInfo#setError(CharSequence), או משתמשים ב-TextView#setError(CharSequence).
במסמכי העזרה של ממשק ה-API announceForAccessibility, שהוצא משימוש, מופיעים פרטים נוספים על חלופות מוצעות.
תמיכה בניווט ב-3 כפתורים
Android 16 为已正确迁移到预测性返回的应用的三按钮导航栏引入了预测性返回支持。长按返回按钮会启动预测性返回动画,让您预览返回滑动手势会打开的界面。
此行为适用于系统中支持预测性返回动画的所有区域,包括系统动画(返回主屏幕、跨任务和跨 activity)。
סמלי אפליקציות בעיצוב עקבי באופן אוטומטי
החל מ-Android 16 QPR 2, מערכת Android מחילה אוטומטית ערכות נושא על סמלי אפליקציות כדי ליצור חוויית מסך בית מגובשת. הבעיה הזו מתרחשת אם אפליקציה לא מספקת סמל אפליקציה מעוצב משלה. אפליקציות יכולות לשלוט בעיצוב של סמל האפליקציה לפי ערכת הנושא על ידי הוספת שכבה מונוכרומטית לסמל האפליקציה הדינמי ותצוגה מקדימה של סמל האפליקציה ב-Android Studio.
גורמי צורה של מכשירים
Android 16 (רמת API 36) כוללת את השינויים הבאים באפליקציות כשהן מוקרנות על מסכים על ידי בעלים של מכשירים וירטואליים.
שינוי הגדרות של בעלי מכשיר וירטואלי
虚拟设备所有者是创建和管理虚拟设备的可信应用或特权应用。虚拟设备所有者在虚拟设备上运行应用,然后将应用投影到远程设备的显示屏上,例如个人电脑、虚拟现实设备或车载信息娱乐系统。虚拟设备所有者使用的是本地设备,例如手机。
按应用替换项
在搭载 Android 16(API 级别 36)的设备上,虚拟设备所有者可以替换其管理的特定虚拟设备上的应用设置。例如,为了改进应用布局,虚拟设备所有者在将应用投影到外部显示屏上时,可以忽略屏幕方向、宽高比和可调整大小性限制。
常见的重大更改
Android 16 的行为可能会影响应用在汽车显示屏或 Chromebook 等大屏幕设备规格上的界面,尤其是那些专为竖屏小显示屏设计的布局。如需了解如何让应用适应所有设备类型,请参阅关于自适应布局。
参考
אבטחה
Android 16 (API ברמה 36) כוללת שינויים שמקדמים את אבטחת המערכת כדי לעזור להגן על אפליקציות ומשתמשים מפני אפליקציות זדוניות.
אבטחה משופרת להגנה מפני התקפות של הפניה אוטומטית של כוונות
Android 16 针对一般的 Intent 重定向攻击提供了默认安全性,并且只需要最低限度的兼容性和开发者更改。
我们引入了默认安全加固解决方案,以应对 Intent 重定向漏洞。在大多数情况下,正常使用 intent 的应用不会遇到任何兼容性问题;我们在整个开发过程中收集了指标,以监控哪些应用可能会出现中断。
Intent 重定向在 Android 中出现,当攻击者可以部分或完全 控制用于在存在漏洞的应用上下文中启动新组件的 intent 内容时,而受害应用会在 intent 的 extra 字段中启动不受信任的子级 intent。这可能会导致攻击者应用在受害应用的上下文中启动私有组件、触发特权操作或获取对敏感数据的 URI 访问权限,从而可能导致数据窃取和任意代码执行。
选择停用 intent 重定向处理
Android 16 引入了一个新 API,允许应用选择停用启动安全保护。在默认安全行为会干扰合法应用用例的特定情况下,这可能是必要的。
对于针对 Android 16(API 级别 36)SDK 或更高版本进行编译的应用
您可以直接对 Intent 对象使用 removeLaunchSecurityProtection() 方法。
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
对于针对 Android 15(API 级别 35)或更低版本进行编译的应用
虽然不建议这样做,但您可以使用反射来访问 removeLaunchSecurityProtection() 方法。
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent", Intent::class.java)
try {
val removeLaunchSecurityProtection = Intent::class.java.getDeclaredMethod("removeLaunchSecurityProtection")
removeLaunchSecurityProtection.invoke(iSublevel)
} catch (e: Exception) {
// Handle the exception, e.g., log it
} // Opt-out from the security hardening using reflection
iSublevel?.let { startActivity(it) }
האפליקציות הנלוות לא מקבלות יותר הודעות על פסק זמן לגילוי
Android 16 introduces a new behavior during
companion device pairing flow to protect the user's location
privacy from malicious apps. All companion apps running on Android 16 are no
longer directly notified of discovery timeout using
RESULT_DISCOVERY_TIMEOUT. Instead, the user is
notified of timeout events with a visual dialog. When the user dismisses
the dialog, the app is alerted of the association failure with
RESULT_USER_REJECTED.
The search duration has also been extended from the original 20 seconds, and the device discovery can be stopped by the user at any point during the search. If at least one device was discovered within the first 20 seconds of starting the search, the CDM stops searching for additional devices.
קישוריות
Android 16 (רמת API 36) כוללת את השינויים הבאים במערך Bluetooth כדי לשפר את הקישוריות למכשירים היקפיים.
טיפול משופר באובדן של קשרים
从 Android 16 开始,蓝牙堆栈已更新,以便在检测到远程配对丢失时提高安全性和用户体验。以前,系统会自动解除配对并启动新的配对流程,这可能会导致意外重新配对。在许多情况下,我们发现应用未以一致的方式处理债券损失事件。
为了统一体验,Android 16 改进了系统的绑定丢失处理。如果之前配对的蓝牙设备在重新连接时无法进行身份验证,系统会断开关联,保留本地配对信息,并显示系统对话框,告知用户配对已断开并指示他们重新配对。