Android 16 开发者适配文档

1、应用适配 -> target36以上

1.1 scheduleAtFixedRate方法适配

说明:

ScheduledExecutorService中的scheduleAtFixedRate接口,可以设置任务在一定周期后,定期启动,比如5秒自动启动一次。但由于进程可能不在有效的生命周期,任务会错过执行,从而出现任务堆叠。

在Android 16之前,当应用返回到有效的生命周期时,所有堆叠的任务都会立即执行。

在Android 16上,当应用返回到有效的生命周期,系统只会立即执行一次未执行的任务。

在Android16上进行多次测试,每当应用重新返回到有效生命周期时,会在大约10ms以内执行两次任务,大概可以解释为一次未执行的任务,一次是当前该执行的任务,总之会在短时间内运行两次任务。

影响:

应用后台累计的定时任务,返回前台,不再会出现任务重复执行,可以减少无效的性能开支。

适配建议:

开发者需要根据任务的类型确定是否有影响,如果是需要随着时间进行固定次数的执行,建议更改方式。


1.2 优雅字体 API 已废弃并停用

说明:

以 Android 15(API 级别 35)为目标平台的应用的 elegantTextHeight属性默认设置为true,从而将紧凑字体替换为更易于阅读的字体。您可以通过将elegantTextHeight属性设置为false来替换此设置。

然而Android 16 弃用了 elegantTextHeight属性,所以如果应用以 Android 16 为目标平台,系统会忽略该属性。这意味着将默认使用优雅字体。

影响:

以 Android 16 为目标平台的应用将默认使用优雅字体,elegantTextHeight属性设置为false将会失效。

适配建议:

应用应调整所有布局,以确保以阿拉伯语、老挝语、缅甸语、泰米尔语、古吉拉特语、卡纳达语、马拉雅拉姆语、奥里亚语、泰卢固语或泰语呈现一致且可持续的文字。


1.3 自适应布局

说明:

此特性在Android 16.0提出,应用的targetsdk等于36且运行在Android 16设备上生效。此特性主要是对最小宽度大于等于600dp的显示屏上生效,即在大屏设备上,系统会忽略应用对屏幕方向、尺寸可调整性和宽高比限制。因此当应用升级targetsdk到36后,针对大屏设备必须要适配全屏显示和横竖屏显示,系统会忽略应用固定比例显示和固定屏幕方向显示。

影响:

忽略屏幕方向、可调整大小和宽高比限制可能会影响应用在某些设备上的界面,尤其是针对锁定在纵向模式的小布局设计的元素:例如,拉伸的布局、屏幕外动画和组件等问题。对宽高比或屏幕方向做出的任何假设都可能会导致应用出现视觉问题。详细了解如何避免这些问题并改进应用的自适应行为。

允许设备旋转会导致重新创建更多 activity,如果未正确保留用户状态,可能会导致丢失用户状态。如需了解如何正确保存界面状态,请参阅保存界面状态

在大屏设备上,以下清单属性和运行时 API 在全屏或多窗口模式下将不起作用:

同时对于 screenOrientationsetRequestedOrientation() 和 getRequestedOrientation(),系统会忽略以下值:

  • portrait
  • reversePortrait
  • sensorPortrait
  • userPortrait
  • landscape
  • reverseLandscape
  • sensorLandscape
  • userLandscape

另外对于显示是否支持可调整大小来说,android:resizeableActivity="false"android:minAspectRatio 和 android:maxAspectRatio 都不会产生任何效果。

在以下情况下,Android 16 的屏幕方向、尺寸调整和宽高比限制不再适用:

  • 游戏(基于 android:appCategory 标志)
  • 用户在设备的宽高比设置中明确选择启用应用的默认行为
  • 屏幕宽度小于 sw600dp 的屏幕

适配建议:

Android系统提供了暂时缓冲此特性生效的配置方式,目的是给应用一定的时间去适配此特性,配置方式可能在Android 17会取消,因此应用升级targetsdk后尽快进行大屏适配。

如需停用特定 activity,请声明 PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY 清单属性:

<activity ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
  ...
</activity>

如果应用的太多部分不支持 Android 16,您可以在应用级别应用相同的属性,以完全停用该功能:

<application ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
</application>


1.4 需要迁移或停用预测性返回

说明:

对于以 Android 16 或更高版本为目标平台且在 Android 16 或更高版本的设备上运行的应用,预测性返回系统动画(返回主屏幕、跨任务和跨 activity)默认处于启用状态。此外,系统不会调用 onBackPressed,也不会再调度 KeyEvent.KEYCODE_BACK

如果您的应用拦截了返回事件,并且您尚未迁移到预测性返回,请更新应用以使用受支持的返回导航 API;或者,在应用的 AndroidManifest.xml 文件的 <application> 或 <activity> 标记中将 android:enableOnBackInvokedCallback 属性设置为 false,以暂时停用此功能。

影响:

对于target为 Android 16 的应用,需要 适配back新api 或者 禁用可预测返回手势。

Android 16 添加了新 API,可帮助您在手势导航中启用预测性返回系统动画,例如“返回主屏幕”动画。通过使用新的 PRIORITY_SYSTEM_NAVIGATION_OBSERVER 注册 onBackInvokedCallback,您的应用可以在系统处理返回导航时接收常规的 onBackInvoked 调用,而不会影响正常的返回导航流程。

Android 16 还添加了 finishAndRemoveTaskCallback() 和 moveTaskToBackCallback。通过向 OnBackInvokedDispatcher 注册这些回调,系统可以在调用返回手势时触发特定行为并播放相应的提前动画。


1.5 健康与健身权限适配

说明:

安卓16升级到targetSDK 36的应用,BODY_SENSORS 权限将过渡到 android.permissions.health(健康数据共享权限) 下的精细权限。主要包括有使用健身健康功能的以下数据类型、API 和前台服务类型:

  • 来自 Wear 健康服务的 HEART_RATE_BPM
  • Android Sensor Manager 中的 Sensor.TYPE_HEART_RATE
  • Wear ProtoLayout 中的 heartRateAccuracy 和 heartRateBpm
  • FOREGROUND_SERVICE_TYPE_HEALTH,其中需要使用相应的 android.permission.health 权限来替代 BODY_SENSORS

如果应用有使用这些 API,之前需要 BODY_SENSORS 或 BODY_SENSORS_BACKGROUND 的权限才可以使用,升级到targetSDK 36现在都需要改为申请相应的 android.permissions.health 权限。

例如:

如需在使用期间监测心率、血氧饱和度或体表温度:请请求 android.permissions.health 下的精细权限,例如 READ_HEART_RATE,而不是 BODY_SENSORS

对于后台传感器访问权限:请求 READ_HEALTH_DATA_IN_BACKGROUND,而不是 BODY_SENSORS_BACKGROUND

影响:

安卓16升级到targetSDK 36的应用,之前需要BODY_SENSORS授权才能使用的API,如果不适配会无法使用。

适配建议:

有使用上述BODY_SENSORS 或 BODY_SENSORS_BACKGROUND管控的API的应用需要适配。

另外需要注意的是升级使用 READ_HEART_RATE 及其它精细化权限时,必须声明一个用于展示隐私政策的 Activity(与 Health Connect 要求一致)。

如未向用户清晰说明权限用途,系统将撤销相关权限,应用也就无法正常访问健康数据。


1.6 本地网络权限

说明:

具有 INTERNET 权限的任何应用都可以访问 LAN 上的设备。这样一来,应用便可轻松连接到本地设备,但这也可能会影响隐私,例如形成用户的指纹,以及充当位置信息的代理。

本地网络保护项目旨在通过将对本地网络的访问权限置于新的运行时权限后面来保护用户的隐私。

发布计划

这项更改将在两个版本(分别为 25Q2 和 TBD)之间部署。 开发者必须遵循 25Q2 的相关指南并分享反馈,因为这些保护措施将在较新的 Android 版本中强制执行。此外,他们需要按照以下指南更新依赖于隐式本地网络访问权限的场景,并为用户拒绝和撤消新权限做好准备。

在 Android 16(25Q2)期间,开发者可以通过 ADB App-Compat 标志显式开启或关闭此保护,以便测试和反馈;未来该权限将在较新的 Android 版本中强制执行

影响:

任何直接或间接(mDNS、SSDP、NsdManager、原始套接字)对本地网络的 I/O 操作(TCP/UDP 的出/入站、广播/多播)均受限。该限制在底层网络栈中统一生效,不依赖特定库或语言。

如果 DNS 服务器位于本地网络(UDP 53 端口),则对该流量不受限,避免影响域名解析。

用例类型本地网络保护开启本地网络保护关闭
出站 TCP 连接EPERM/失败正常
入站 TCP 监听EPERM/失败正常
UDP 单播/多播/广播EPERM/失败正常

适配建议:

声明并请求新权限

  • 在 AndroidManifest.xml 中声明 android.permission.NEARBY_WIFI_DEVICES(未来将包含本地网络操作权限)。
  • 在运行时向用户请求并处理“允许/拒绝”逻辑。


2、应用适配 -> 所有应用

2.1 ART内部变更

说明:

ART 性能优化与新 Java 功能支持:

性能提升:ART 的更新包含了针对性能的多个优化,尤其是内存管理、垃圾回收(GC)和方法调用效率方面的提升。

Java 功能支持:新的 ART 更新增加了对更多 Java 特性的支持,能够更好地与现代 Java 版本和编译技术兼容。

影响:

任何依赖于 ART 内部结构(如非 SDK 接口)的应用或库,在搭载 Android 16 的设备上或通过 Google Play 系统更新更新 ART 模块的较低版本的设备上,可能会遇到兼容性问题。这是因为 ART 内部结构会随着更新发生变化,从而导致依赖这些内部结构的代码无法正常工作。

适配建议:

应用应尽量避免依赖 ART 内部结构或使用非公共 API,否则一旦 ART 实现发生变更,就可能引发严重的兼容性问题。目前已发现以下几类典型异常:

  1. HiddenApiByPass类闪退异常请注意,HiddenApiBypass 并非官方支持的 SDK,它依赖于 Android ART 虚拟机的内部实现细节,包括 java.lang 包中的私有类结构和字段。这种做法具有高度不稳定性和兼容性风险,在不同 Android 版本之间可能导致应用崩溃或行为异常。Google 官方也明确指出:“Updating the library to a newer version is not the right fix, as the library’s approach explicitly relies on the class structure and even private field names in java.lang package (which are implementation details).”这意味着,即使你使用了最新版本的SDK库,也无法从根本上解决其绕过系统限制所带来的风险。我们强烈建议开发者:
    • 避免使用 HiddenApiBypass 或类似机制访问隐藏 API;
    • 关注官方对 灰名单/隐藏 API 的政策变动,以确保应用兼容性和稳定性。
    使用不受支持的方法绕过系统限制,不仅违反 Play 安全政策,还可能在未来 Android 系统中完全失效,请开发者谨慎评估并尽量采用官方支持的方案进行替代。
  2. dpt-shell加固方案该开源加固工具在 Android 16 中,由于 ART ClassLinker 的 DefineClass 方法变更,导致应用启动即闪退。dpt-shell 已发布兼容补丁,相关应用请尽快升级到最新版本。
  3. 其它加固方案部分商业加固应用在 Android 16 上因 LoadMethod 接口弃用以及严格校验 annotation_set_item 对齐,导致启动崩溃。加固厂商已发布适配版本,请三方应用及时同步更新。


2.2 增强了针对 intent 重定向攻击的安全性

说明:

增强了对intent重定向攻击的安全防范

Android 16 提供了针对常规 Intent 重定向攻击的默认安全防护,并且只需进行最少的兼容性和开发者更改。

我们将默认引入针对 Intent 重定向漏洞的安全增强解决方案。在大多数情况下,使用 intent 的应用通常不会遇到任何兼容性问题;我们在整个开发过程中收集了指标,以监控哪些应用可能会出现故障。

当攻击者部分或完全控制用于在存在漏洞的应用上下文中启动新组件的 intent内容时,就会出现 Android 中的 intent重定向问题,而受害应用会在 intent(“顶级”intent)的 extras 字段中启动不可信的子级 intent。这可能会导致攻击者应用在受害应用上下文中启动私有组件、触发特权操作或获得对敏感数据的 URI 访问权限,从而可能导致数据被盗和任意代码执行。

停用 intent 重定向处理

Android 16 引入了一个新 API,允许应用选择停用启动安全保护。在默认安全行为干扰合法应用用例的特定情况下,这可能很有必要。

  • 对于以 Android 16 或更高版本为目标平台的应用您可以直接对 intent 对象使用 removeLaunchSecurityProtection() 方法。
  • 对于以 Android 15(API 级别 35)或更低版本为目标平台的应用虽然不建议这样做,但您可以使用反射来访问 removeLaunchSecurityProtection() 方法。

影响:

这种“用户选择启用”属性意味着,开发者必须在应用清单中明确启用该功能,才能使其生效。因此,只有开发者符合以下条件的应用会受到该功能的影响:

  • 了解“更安全的 intent”功能及其优势。
  • 主动选择在应用中采用更严格的 intent 处理做法。

这种“用户选择接受”方法可最大限度地降低破坏可能依赖于当前安全性较低的 intent解析行为的现有应用的风险。

虽然在 Android 16 中的初始影响可能有限,但“更安全的 intent”计划制定了路线图,以便在未来的 Android 版本中产生更广泛的影响。我们的计划是最终将严格的 intent解析设为默认行为。

通过提高恶意应用利用 intent解析机制中的漏洞的难度,更安全的 intent功能有望显著增强 Android 生态系统的安全性。

不过,必须谨慎管理向“用户选择拒绝才无效”和强制执行过渡,以解决与现有应用的潜在兼容性问题。

另外停用该功能(调用removeLaunchSecurityProtection之后),攻击者应用可以在受害应用上下文中启动私有组件、触发特权操作或获得对敏感数据的 URI 访问权限,从而可能导致数据被盗和任意代码执行,不建议模块调用。

适配建议:

开发者需要在应用清单中使用 intentMatchingFlags 属性明确启用更严格的 intent匹配。以下示例展示了如何为整个应用选择启用该功能,但在接收器上停用/选择停用该功能:

<application android:intentMatchingFlags="enforceIntentFilter">
    <receiver android:name=".MyBroadcastReceiver" android:exported="true" android:intentMatchingFlags="none">
        <intent-filter>
            <action android:name="com.example.MY_CUSTOM_ACTION" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.example.MY_ANOTHER_CUSTOM_ACTION" />
        </intent-filter>
    </receiver>
</application>

注意: 此属性可在 <application> 标记以及 <activity>、<activity-alias>、<receiver>、<service>、<provider> 等组件标记中指定,并且组件上的属性可用于替换 <application> 标记上的属性。

有关支持的标志的更多信息:

标志名称说明
enforceIntentFilter对传入 intent 强制执行更严格的匹配
none停用针对传入 intent 的所有特殊匹配规则。指定多个标志时,系统会通过将“none”标志的优先级设为最高来解析冲突的值
allowNullAction放宽匹配规则,以允许没有匹配操作的 intent。此标志应与“enforceIntentFilter”结合使用,以实现特定行为


2.3 JobScheduler配额优化

说明:

从 Android 16 起,系统将基于 三大场景 动态限制后台任务执行时长:

  1. 应用活跃度:根据应用后台使用频率(如「活跃」「受限」分组)分配不同配额,高频应用配额更高。
  2. 可见性变化:任务启动时应用在前台,但转入后台后仍需遵守配额限制(原可无限执行)。
  3. 前台服务绑定:即使关联前台服务,任务执行时长仍受限制(此前可绕过限制)。

其应用在不同分组下的配额如下图所示:

影响:

此规则影响 WorkManagerJobSchedulerDownloadManager调度的所有任务。

  1. 任务中断:后台大文件传输、长时间数据同步等任务可能被强制中断。
  2. 延迟执行:低活跃度应用的任务可能延迟数小时触发。
  3. 兼容性问题:依赖前台服务保活的后台逻辑需重构。

适配建议:

  1. 检查应用程序中的后台任务,确保在新的配额规则下能够正常执行。
  2. 尽量减少不必要的后台任务,确保高优先级任务可以在合理的配额内完成。
  3. 考虑使用 WorkManager 或其他适合处理后台工作的 API 来管理任务,尤其是用户发起的数据传输等重要操作。
  4. 确保应用在各种待机分桶和任务执行条件下的表现符合预期。可通过系统接口实现监测任务停止或未执行的原因,并根据需要调整任务逻辑。

应用如果想知道有没有受到该策略影响,可以通过下面方式来判断:

@Override
public boolean onStopJob(JobParameters params) {
    if (params.getStopReason() == JobParameters.STOP_REASON_QUOTA) {
        // To do
    }
    return false;
}


2.4 被废弃的空作业停止原因

说明:

如果与作业关联的 JobParameters 对象已被垃圾回收,但尚未调用 JobService#jobFinished(JobParameters, boolean) 来指示作业已完成,则会发生作业被废弃的情况。这表示作业可能会在应用不知情的情况下运行和重新调度。

依赖于 JobScheduler 的应用不会维护对 JobParameters 对象的强引用,并且超时现在将获得新的作业停止原因 STOP_REASON_TIMEOUT_ABANDONED,而不是 STOP_REASON_TIMEOUT

如果新的作业被废弃停止原因频繁出现,系统会采取缓解措施来降低作业频率。

应用应使用新的停止原因来检测和减少被废弃的作业。

如果您使用的是 WorkManagerAsyncTask 或 DownloadManager,则不会受到影响,因为这些 API 会代表您的应用管理作业生命周期。

影响:

如果作业相关的 JobParameters 被垃圾回收,但没有显式调用 jobFinished,那么作业可能会在不通知应用的情况下被终止或重新调度。

如果频繁出现 STOP_REASON_TIMEOUT_ABANDONED 停止原因,系统会采取措施来降低作业的频率,以免造成不必要的资源消耗。

适配建议:

  1. 避免手动管理作业生命周期:尽量避免直接依赖 JobScheduler 和手动管理 JobParameters,推荐使用如 WorkManager 等高级 API 来管理作业生命周期,它会自动处理作业的结束和重新调度。
  2. 确保及时调用 jobFinished:如果应用确实依赖 JobScheduler,则应确保在作业完成后,调用 jobFinished(JobParameters, boolean) 方法来标记作业的结束,防止作业被废弃。
  3. 使用新的停止原因:开发者应根据新的停止原因 STOP_REASON_TIMEOUT_ABANDONED 来检测是否存在作业生命周期管理不当的问题,并进行必要的优化。

应用如果需要判断停止原因,可以通过下面方式去进行判断:

@Override
public boolean onStopJob(JobParameters params) {
    if (params.getStopReason() == JobParameters.STOP_REASON_TIMEOUT_ABANDONED) {
        // To do
    }
    return false;
}


2.5 完全弃用JobInfo#setImportantWhileForeground

说明:

JobInfo.Builder#setImportantWhileForeground(boolean) 方法用于在调度应用位于前台或暂时豁免于后台限制时指示作业的优先级。

自 Android 12(API 级别 31)起,此方法已废弃。从 Android 16 开始,它不再有效,系统会忽略调用此方法。

此功能移除也适用于 JobInfo#isImportantWhileForeground()。从 Android 16 开始,如果调用该方法,该方法会返回 false

影响:

将导致一些依赖该标志的任务(如下载任务、实时数据同步任务、位置更新任务等)在前台时不再享有优先执行的权利,可能导致任务延迟执行或因资源限制被暂停,影响用户体验。

某些任务本应该在前台时被优先执行(如快速同步数据、推送通知接收、实时流媒体播放等),现在这些任务的执行可能会受到后台任务的影响,从而导致更高的延迟或者任务失败。

适配建议:

移除setImportantWhileForeground相关依赖调用,如果是耗时短且高优先级的任务建议使用加急任务——setExpedited()来替代,而且该接口不依赖于前后台状态。

JobInfo.Builder builder = new JobInfo.Builder(555000003, new ComponentName("com.example.bgservicedemo", MyJobService.class.getName()))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setRequiresDeviceIdle(false)
.setExpedited(true);

JobScheduler js = (JobScheduler)context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
js.schedule(builder.build());


2.6 有序广播优先级有效范围不再是全局

说明:

Android 应用可以为广播接收器定义优先级,以控制接收器接收和处理广播的顺序。对于清单声明的接收器,应用可以使用 android:priority 属性来定义优先级;对于上下文注册的接收器,应用可以使用 IntentFilter#setPriority() API 来定义优先级。发送广播时,系统会按接收器的优先级(从高到低)将其传送给接收器。

在 Android 16 中,无法保证使用 android:priority 属性或 IntentFilter#setPriority() 在不同进程中传送广播的顺序。广播优先级仅在同一应用进程内有效,而不会跨所有进程有效。

此外,广播优先级将自动限制在 (SYSTEM_LOW_PRIORITY + 1, SYSTEM_HIGH_PRIORITY – 1)的范围内。只有系统组件才能将 SYSTEM_LOW_PRIORITYSYSTEM_HIGH_PRIORITY设置为广播优先级。

如果您的应用执行以下任一操作,可能会受到影响:

  1. 您的应用声明了具有相同广播 intent 的多个进程,并且希望根据优先级以特定顺序接收这些 intent
  2. 您的应用进程与其他进程交互,并期望以特定顺序接收广播 intent

如果进程需要相互协调,则应使用其他协调渠道进行通信。

影响:

具体来说,以下两类场景会受到影响:

  1. 同一应用的多个进程:如果一个应用声明了多个进程,并且在不同进程中注册了相同的广播接收器,且期望根据优先级顺序处理这些广播,系统将不再保证这种顺序。广播只保障进程内的优先级排序,但跨进程的优先级比较会失效。
  2. 跨进程交互的应用:如果一个应用的进程与其他应用的进程交互,且期望在接收到广播时按照某种顺序进行处理,系统也不再保证跨进程的广播顺序。

适配建议:

如果你的业务依赖有序广播,建议逐步重构旧代码,减少对跨进程有序广播的依赖。可以考虑使用其他 IPC(进程间通信)机制来替代广播,或使用 JobScheduler和 WorkManager等任务调度工具来确保任务顺序的执行。


2.7 无边框设计停用退出选项

说明:

Android 15 强制为以 Android 15(API 级别 35)为目标平台的应用启用边到边,但您的应用可以通过将 R.attr#windowOptOutEdgeToEdgeEnforcement 设为 true 来选择停用。对于以 Android 16 为目标平台的应用,R.attr#windowOptOutEdgeToEdgeEnforcement 已废弃并处于停用状态,并且您的应用无法选择停用全屏显示。

如需在 Android 16 Beta 版 2 中进行测试,请确保您的应用支持边到边,并移除对 R.attr#windowOptOutEdgeToEdgeEnforcement 的任何使用。如需支持边到边,请参阅 Compose 和 View 指南。如有疑虑,请在反馈页面上通过问题跟踪器与我们联系。

影响:

在 Android 16 中,边到边(Edge-to-Edge)设计的强制性要求已经更加严格,应用不可以选择停用全屏显示,未适配应用可能会存在UI遮挡或显示异常等问题。

适配建议:

支持边到边设计: 在 Android 16 中,应用必须适应边到边的设计标准。这意味着应用界面将自动填充整个屏幕,而不再有传统的系统状态栏和导航栏的空间占据。

移除 windowOptOutEdgeToEdgeEnforcement的使用: 如果你的应用在 Android 15 中使用了 R.attr#windowOptOutEdgeToEdgeEnforcement 来停用边到边显示,在 Android 16 中应该移除该属性。强制启用全屏显示意味着该属性已经失效。


2.8 后台启动Activity权限变更

说明:

MODE_BACKGROUND_ACTIVITY_START_ALLOWED在Android 16上已经被废弃,新增MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS 和MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE

MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS允许 PendingIntent获得所有后台启动 Activity 的权限,适用于需要绕过后台启动限制的特定场景。但由于这种行为可能对用户体验产生较大影响(例如意外的界面切换或中断用户当前操作),因此应谨慎使用。

MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE,以确保只有在应用可见时才启动后台 Activity,从而最大限度地降低对用户的干扰。

影响:

废弃MODE_BACKGROUND_ACTIVITY_START_ALLOWED意味着 Android 系统将不再对该flag提供支持。虽然应用依然能够使用它,但 Android 系统可能不再保证它在所有设备和系统版本中正常工作,尤其是在后续更高版本的 Android 中,废弃的 API 很可能会被完全移除。

适配建议:

开发者应该使用系统推荐的新的flag来确保应用后台Activity启动行为与最新的 Android 系统兼容:

使用 MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE来确保只有在应用可见时才启动Activity

使用 MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS来允许应用在任何时候从后台启动Activity


2.9 自动填充API弃用

说明:

void notifyVirtualViewsReady(View, SparseArray<VirtualViewFillInfo>) Now deprecated.

boolean showAutofillDialog(View) Now deprecated.

boolean showAutofillDialog(View, int) Now deprecated.

Android 16上Autofill这几个接口已被弃用,自动填充的对话框和视图显示现在完全由框架控制,自动填充提供者不再需要手动通知虚拟视图准备好。

影响:

Android 16上Autofill这三个接口调用将无效。

适配建议:

针对Android 16版本移除这三个接口调用(同时也要考虑兼容Android 16之前的版本),开发者可通过配置autofillHints 属性标识可填充的字段内容类型(用户名、密码、邮箱等),框架会在需要时自动显示填充建议。


2.10 用于处理键盘绑定丢失和加密更改的新 intent

说明:

Android 16 引入了 2 个新 intent,以改善与外围设备(键盘)的连接。

影响:

以 Android 16 为目标平台的应用现在可以:

在检测到远程键盘连接丢失时接收 ACTION_KEY_MISSING intent,以便提供更具信息量的用户反馈并采取适当的措施。

每当链接的加密状态发生变化时,都会收到 ACTION_ENCRYPTION_CHANGE intent。这包括加密状态更改、加密算法更改和加密密钥大小更改。如果应用在稍后收到 ACTION_ENCRYPTION_CHANGE intent 时成功加密了链接,则必须将该绑定视为已恢复。

适配建议:

如果您的应用目前使用自定义机制来处理键盘键失效,请迁移到新的intent ACTION_KEY_MISSING 以检测和管理键盘键失效事件。我们建议您的应用在发起设备忘记和重新配对之前,引导用户确认远程设备是否在有效范围内。

此外,如果设备在收到 ACTION_KEY_MISSING intent 后断开连接,您的应用应注意重新连接到设备,因为该设备可能已不再与系统绑定。


2.11 Java API变更

2.11.1 java.lang.Thread类变更

部分方法移除说明:

Removed Methods

int countStackFrames()    void destroy()    void resume()   void stop(Throwable)  void suspend()

这些方法的移除是为了减少使用不当可能引起的线程安全问题和死锁风险。

影响:

调用destroystopresumesuspend接口会直接抛UnsupportedOperationException(Android 14/15上也是如此)

适配建议:

推荐使用以下方式代替这些被移除的方法:

  1. 线程中断:使用 Thread.interrupt() 来优雅地停止线程。
  2. 线程协作:使用 wait()notify() 或 java.util.concurrent 包中的同步工具类(如 CountDownLatchSemaphoreLock等)来进行线程之间的协作。
  3. 线程池:使用 ExecutorService或 ForkJoinPool等线程池来管理线程的生命周期,而不是直接管理 Thread

部分方法弃用说明:

  1. void checkAccess() Now deprecated.checkAccess() 方法用于判断当前运行的线程是否有权限修改目标线程。对于线程的安全访问检查,未来的 Android 系统可能不再使用传统的 Security Manager,因此开发者应该避免依赖于 checkAccess() 方法。
  2. long getId() Now deprecated.  Added Methods  long threadId()getId() 方法已在 API level Baklava 中被弃用,原因是该方法可以被重写,可能会导致不一致行为。threadId() 被引入作为替代,提供了一个更为一致和安全的方式来获取线程ID。

影响:

  1. void checkAccess()方法源码实现已全被注释掉,因此调用该接口将无效。
  2. long getId()接口未声明为final,意味着可以重写也就无法保证该接口返回的线程ID一致性,因此建议使用long threadId()替换。

适配建议:

  1. 如果开发者在项目中使用了 checkAccess(),那需要移除相关代码,因为在未来的 Android 版本中,可能会完全移除 SecurityManager,这会导致你的应用无法正常工作。目前也没有新的替代方法可以使用,因此开发者不应该再使用该方法来进行线程访问权限的检查。
  2. 对于兼容性和未来的可维护性,开发者应逐步弃用 getId(),并使用 threadId() 作为获取线程 ID 的首选方法。


2.11.2 java.util.Locale类变更

说明:

Locale(String) Now deprecated.

Locale(String, String) Now deprecated.

Locale(String, String, String) Now deprecated.

Java 对 Locale类的一些构造方法进行了弃用,这些方法的弃用不意味着它们会立即被删除,但建议开发者使用新的方法。

Added Methods:

Locale of(String)

Locale of(String, String)

Locale of(String, String, String)

新增构造方法用于创建新的 Locale 实例,提供了比旧构造方法更清晰和明确的创建方式。

影响:

虽然这些 Locale 构造函数已经标记为 @Deprecated,但是它们的源码实现仍然保留并且可以正常调用。

适配建议:

开发者应该逐步迁移至Locale.of() 系列方法,以确保代码的兼容性和可维护性,尤其是在未来版本的 Android 中,这些被弃用的构造函数可能会完全移除。


2.12 改进了无障碍功能API

说明:

Android 16 添加了新的无障碍功能 API 和功能。

  1. 向 TtsSpan 添加了时长Android 16 使用 TYPE_DURATION扩展了 TtsSpan,其中包含 ARG_HOURSARG_MINUTES和 ARG_SECONDS。这样,您就可以直接为时长添加注释,确保通过 TalkBack 等服务获得准确且一致的文本转语音输出。对原tts播报内容扩展,增加了应用可以通过TtsSpan实现小时、分、秒的播报。
  2. 支持具有多个标签的元素Android 目前允许界面元素从其他元素派生其无障碍功能标签,现在还支持关联多个标签,这是 Web 内容中常见的情况。通过在 AccessibilityNodeInfo 中引入基于列表的 API,Android 可以直接支持这些多标签关系。在进行这项更改的过程中,我们已弃用 AccessibilityNodeInfo#setLabeledBy 和 #getLabeledBy,改用 #addLabeledBy#removeLabeledBy 和 #getLabeledByList
  3. 改进了对可展开元素的支持Android 16 添加了无障碍功能 API,可让您传达互动元素(例如菜单和展开式列表)的展开或收起状态。通过使用 setExpandedState设置展开状态,并使用 CONTENT_CHANGE_TYPE_EXPANDED 内容更改类型调度 TYPE_WINDOW_CONTENT_CHANGED AccessibilityEvents,您可以确保 TalkBack 等屏幕阅读器会读出状态更改,从而提供更直观、更包容的用户体验。例如菜单和展开式列表主动发送CONTENT_CHANGE_TYPE_EXPANDED 事件去通知读频软件播报,AccessibilityNodeInfo.setExpandedState 设置对应的状态值,控制播报内容。
  4. 不确定进度条Android 16 添加了 RANGE_TYPE_INDETERMINATE,让您可以为确定性和不确定性的ProgressBar公开 RangeInfo,从而让 TalkBack 等服务能够更一致地为进度指示器提供反馈。
  5. 三种状态的复选框Android 16 中的新 AccessibilityNodeInfo getChecked 和 setChecked(int) 方法现在除了“已选中”和“未选中”之外,还支持“部分选中”状态。此字段取代了已废弃的布尔值 isChecked 和 setChecked(boolean)
  6. 补充说明如果您给 ViewGroup 设置了 contentDescription,不可聚焦的子视图的内容描述就会被忽略,没办法通过TalkBack播报完整的信息,Android 16 添加了 setSupplementalDescription,以便您提供用于提供 ViewGroup 相关信息的文本,而不会覆盖其子项中的信息。
  7. 必填表单字段AccessibilityNodeInfo 新增了一个字段:fieldRequired,对于各种填表类场景或账号密码等登录场景,如账号、密码、隐私条款必须勾选的复选框都可以通过设置fieldRequiredture;用于盲人识别哪些字段是必填的,并进行对应内容的输入填写。

影响:

针对无障碍场景进行扩展,优化了下使用场景和功能。

适配建议:

开发者在遇到以上场景时可以优化无障碍体验,提示应用对于盲人群体的应用体验。


3、新功能和api

3.1 密钥共享API

说明:

Android 16 添加了一些 API,这些 API 支持与其他应用共享对 Android Keystore 密钥的访问权限。新的 KeyStoreManager 类支持按应用 uid 授予和撤消对密钥的访问权限,并包含一个供应用访问共享密钥的 API。

KeyStoreManager中的关键api:

List<X509Certificate> getGrantedCertificateChainFromId(long id)返回一个X509Certificate实例列表,该列表代表之前使用提供的id与app共享的密钥的证书链。
Key getGrantedKeyFromId(long id)返回之前与该应用共享的具有指定id的密钥
KeyPair getGrantedKeyPairFromId(long id)返回一个包含公钥和私钥的KeyPair,这些密钥与之前使用提供的id与app共享的密钥相关联。
byte[] getSupplementaryAttestationInfo(int tag)返回解析指定标签(tag)认证值所需的专属数据。
long grantKeyAccess(String alias, int uid)授予设备上具有指定uid的另一个应用程序对调用应用程序存储在指定别名下的密钥的访问权限。
void revokeKeyAccess(String alias, int uid)撤销之前授予设备上具有指定uid的另一个应用程序的、存储在调用应用程序命名空间中指定别名下的密钥的访问权限。

影响:

两个app之间共享keystore秘钥,需要谨慎使用,防止机密数据被非预期的授权app解密导致泄露。

适配建议:

有需要共享keystore密钥的应用可以使用新的共享api满足。


3.2 在 ApplicationStartInfo 中增加启动的组件类型

说明:

在Android 15新增的ApplicationStartInfo允许一个应用可以了解到进程启动的原因、启动类型、启动时间、限制和其他的实用数据。

Android 16添加了getStartComponent(),用于区分触发启动的组件类型,有助于优化应用的启动流程。

对应的启动类型为START_COMPONENT_ACTIVITYSTART_COMPONENT_BROADCASTSTART_COMPONENT_CONTENT_PROVIDERSTART_COMPONENT_SERVICESTART_COMPONENT_OTHER。分别可以判断是从activitybroadcastcontentProviderserviceorther 这五种情况启动。

影响:

应用可以判断自身启动的原因和类型。

适配建议:

应用可通过判断启动类型进行启动流程优化,仅加载特定类型的依赖项。


3.3 以进度为中心的通知

3.3.1 效果

Android 16 引入了以进度为中心的通知,可帮助用户顺畅地跟踪用户发起的端到端历程。

Notification.ProgressStyle 是一种新的通知样式,可让您创建以进度为中心的通知。主要用例包括共享车辆、送货和导航。在 Notification.ProgressStyle 类中,您可以使用细分来表示用户体验历程中的状态和里程碑。

如需了解详情,请参阅以进度为中心的通知文档页面。


3.3.2 模版样式

3.3.3 使用方式

var ps =
    Notification.ProgressStyle()
        .setStyledByProgress(false)
        .setProgress(456)
        .setProgressTrackerIcon(Icon.createWithResource(appContext, R.drawable.ic_car_red))
        .setProgressSegments(
            listOf(
                Notification.ProgressStyle.Segment(41).setColor(Color.BLACK),
                Notification.ProgressStyle.Segment(552).setColor(Color.YELLOW),
                Notification.ProgressStyle.Segment(253).setColor(Color.WHITE),
                Notification.ProgressStyle.Segment(94).setColor(Color.BLUE)
            )
        )
        .setProgressPoints(
            listOf(
                Notification.ProgressStyle.Point(60).setColor(Color.RED),
                Notification.ProgressStyle.Point(560).setColor(Color.GREEN)
            )
        )


3.4 使用用带缓存的Binder接口减少IPC调用次数

说明:

安卓16上新增两个与Binder相关的接口:

  • IpcDataCache
  • RateLimitingCache

以上接口都是对常规binder调用的包装,通过在客户端中添加缓存,解决频繁binder导致的时延、资源浪费的问题。

IpcDataCache 基于主动缓存失效机制,客户端发起binder调用后,会将数据缓存到内存中,后续在发起同样的binder调用时,如果缓存没有失效,会从缓存中取数据,以减少IPC次数,需要注意此接口需要客户端和服务端共同适配才能生效。

RateLimitingCache 基于时间窗口的缓存机制,限制时间窗口内最大的IPC次数,每次IPC调用会把结果缓存到内存中,如果窗口时间内IPC次数超出阈值,则从缓存中返回结果,此接口只需要客户端适配接口。

影响:

如果模块不对现有的binder调用进行改造,没有影响。

源码中已经有部分binder调用使用此接口进行了改造,在ard16上频繁调用这些接口的性能优于ard16之前。部分接口如下:

适配建议:

模块遇到频繁binder引起的性能、功耗等问题后,如果从代码逻辑上无法轻易修复,可以考虑使用此方案,具有显著的性能优势。


3.5 自适应刷新率

说明:

Android 15 中引入的自适应刷新率 Adaptive refresh rate (ARR) ,从而支持硬件上的显示刷新率能够使用离散的 VSync 步骤适应内容帧速率,从而降低了功耗,同时消除了可能引起卡顿的模式切换。

但是尽管 Android 15 增加了对自适应刷新率的平台级支持,但它并没有为应用提供实际利用它的方法,而在 Android 16 DP2 在恢复 getSupportedRefreshRates()  的同时引入了 hasArrSupport() 和 getSuggestedFrameRate(int) ,从而让 App 可以更轻松地适配 ARR。

适配建议:

之前 getSupportedRefreshRates 在 API level 23 的时候被 deprecated  ,改成了 getSupportedModes ,现在它又复活了。

通过 getSuggestedFrameRate(int) 可以在给定描述性帧速率类别的情况下,获取显示器定义的帧速率。

在不需要快速渲染速率的动画可以使用 FRAME_RATE_CATEGORY_NORMAL 来获取建议帧速率, 然后建议的帧速率可以通过 Surface.FrameRateParams.Builder.setDesiredRateRange 设置。


4、参考链接

(1)https://developer.android.com/about/versions/16/features

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/22922,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?