2025年的Android新版本来的比2024年稍早了一些。今年Google非常反常地提前就发布了Android的新版本Android 16 Baklava,整体的计划比往年提前了2~3个月。另外,谷歌把Android 16的代码命名为「Baklava」,这与先前的字母表顺序的点心食物命名方式截然不同,不过「Baklava」巴克拉瓦,又称果仁蜜饼,是一种口味浓郁、甜蜜的土耳其酥皮点心。
谷歌的发布计划
从官方的消息来看会在24年结束Preview,在25年1月其实是Q1就开始Beta release,并在Q2进入Platform Stability,预计上半年就可能会正式发布,整体的节奏较往年提前了约2~3个月(往年是Q1会有Preview,Q2发布Beta,6~7月左右开始Platform Stability,Q3 9月~10月正式发布)。
不过现仍在非常为初始的Preview阶段,后面可能会有变数,官方也没有给具体的计划。但有一点是确定的,那就是今年Android 16的发布肯定较往年会提拉一些,至少提拉2个月。
对于应用开发者来说,更为关心的是API的发布情况,一般情况下API会较系统版本提前一个季度就会正式稳定下来(也即不会再有大的变动),换句话说,今年在Q2就能得到较为稳定的API版本,当然比往年还是有提拉的。
发布计划不受我们控制,了解一下就可以了,下面我们看一下如何用条件区分这些新的API。
区分使用新的API的方式
如果应用不是运行在最新的版本,那么新的API不应该被执行,因此我们需要用条件来区分不同的API版本,用SDK_INT和VERSION_CODES就可以做到。当然,需要先在Android Studio中把SDK中的Android 16 Preview版本下载下来才能编译。
if (SDK_INT >= VERSION_CODES.BAKLAVA) {
// 使用Android 16中才有的API
}
为了能更细致地区分版本,Android 16新增加了一个新的版本常量SDK_INT_FULL,并在VERSION_CODES_FULL中定义了具体的常量值。它可以粒度更细地检查API的版本,分为Major版本和Minor版本。以往的SDK_INT只能区分大的版本(Major版本),这是它们最大的不同。
if (SDK_INT_FULL >= VERSION_CODES_FULL.[MAJOR or MINOR RELEASE]) {
// 用Major版本或者Minor版本才有的API
}
每个Major版本可能会多个Minor版本,如果不想麻烦,可以用Build.getMinorSdkVersion()来从VERSION_CODES_FULL中取出Minor版本号。
注意: SDK_INT_FULL,VERSION_CODES_FULL以及getMinorSdkVersion都是Android 16中新增的API,确保把SDK升级到最新才可以编译成功。
接下来我们重点来看一下新一代的Android带来了哪些变化。
新的功能和新的API
很不幸,Android 16并没有带来全新的功能。只有一些小的新API。
用户体验和系统UI
提供一些的新的API以更好更灵活的控制系统的行为。
可预见的返回更新
Android 16增加了新的API以使能手势导航中的可预见返回系统动画,比如从应用返回到桌面的动画。使用新的PRIORITY_SYSTEM_NAVIGATION_OBSERVER向系统注册一个回调onBackInvokedCallback,每当系统处理一个返回导航时就能够收到onBackInvoked回调,而不影响常规的返回导航流程。
Android 16还增加了两个API finishAndRemoveTaskCallback和moveTaskToBackCallback。通过向OnBackInvokedDispatcher注册这些回调,当执行返回手势时系统就能触发具体的行为和播放相关的动画。
更加丰富的震感反馈
Android 16增加了震感API,能让应用定义震感效果的振幅和频率的曲线,同时屏蔽设备的差异。
性能和电池
Android 16提供了新的API以帮助收集应用的洞察。
系统触发的分析
Android 15添加的ProfilingManager能让应用请求分析数据集。然而,这个分析必须由应用来发起,一些像启动过程以及ANR就很抓取得到(因为应用必须要先正常启动起来后,才能调用ProfilingManager去获取分析数据)。
为了解决这个问题,Android 16在ProfilingManager中增加了系统触发的分析数据。应用可以注册感兴趣的特定场景的trace,诸如冷起动或者ANR,系统会替应用开启和停止trace。trace收集完毕后,结果会传到应用的data目录。
ApplicationStartInfo中增加Start component
ApplicationStateInfo是在Android 15增加的,让应用能够看到进程启动原因,启动类型,启动时间等一系列诊断数据。Android 16增加了方法getStartComponent以辨识哪种组件类型触发的启动,这对于优化应用启动过程将会非常有帮助。
更好的(后台)任务反查
API JobScheduler#getPendingJobReason()能返回任何处于待处理的原因。当然,一个任务可能由于很多种原因待处理。
在Android 16中,增加了一个新的API JobScheduler#getPendingJobReasons(int jobId),用以返回任务处于待处理的多个原因,比如缘于开发者设置了显性的限制或者系统设置的隐性限制。
还增加了一个API JobScheduler#getPendingJobReasonsHistory(int jobId),用以返回最近的限制变更列表。
推荐使用这些API来调试为何后台任务没被执行,尤其是当看到特定任务的成功率降低时,或者特定任务完成有延迟时。例如,在后台更新桌面小部件时失败或者预先拉取任务在应用启动前失败等等。
这也能够更好的帮助你明白因为系统定义的限制还是因为显性的限制而导致特定的任务未执行完成。
自适应刷新频率
Android 15引入的自适应刷新频率(Adaptive refresh rate ARR)通过离散化的VSync步长能够让屏幕刷新频率适配内容频率。这会降低功耗同时消除潜在的掉帧。
Android 16增加了方法hasArrSupport和方法getSuggestedFrameRate(int)以及getSupportedRefreshRates(),让应用容易利用ARR。Jetpack中的很多组件在内部实现上已经利用ARR以增强平滑的滑动,详细的可参见了此文章。
连接
Android 16增加了对WiFi位置安全性的支持,通过这个特性。
媒体
照片选择增强
照片选择器(photo picker)提供了一个安全且内置的方式让应用在用户授权的情况下从存储中选择媒体文件。
Android 16带来的增强点有:
- 嵌入式的图片选择器:新的API能够让应用把图片选择器嵌入到自己的视图中。这会让图片选择看起来更像是应用整体的一部分。后续的Jetpack中会提供可嵌入的图片选择器。
- 图片选择器支持云搜索:新的API在图片选择器将支持云搜索。
隐私
健康连接更新
开发者Preview版本中的健康连接增加了ACTIVITY_INTENSITY(活动强度),依据世界健康组织(WHO)给出的指南中定义的一个新的数据类型。每一条记录将必须包括开始时间,结束时间以及活动强度。
隐私沙盒
Android 16集成了Android隐私沙盒的最新版本,这是一项为保护用户隐私而持续进行的工作。可以查看网站内容以了解更多。
行为变更
比起新的API,Android 16带来的行为变更更值得我们关注,因为这会直接影响所有应用,无论targetSdkVersion是否是Baklava。
核心功能
JobScheduler配额优化
从Android 16开始,以基于以下因素来调整常规任务和加急任务的运行时配额:
- 应用处于哪个等待区:在Android 16中,活跃的等待区会减少限制。
- 如果任务开始执行时应用处于头部状态:在Android 16中,任务启动时,如果应用是用户可见的且应用变成可见后仍在继续执行,会加入到运行时配额中。
- 如果任务执行时正在运行一个前台服务:在Android 16中,当正在执行一个前台服务时,正在执行的任务将加入到运行时配额中。如果任务是用于用户数据传送,建议考虑替换方案。
这些变动将会影响由WorkManager,JobScheduler和DownloadManager调度的任务。如果要调试为何一个任务被终止了,建议通过调用WorkInfo.getStopReason()来打印日志。
也可以通过Android 16新增加的API JobScheduler#getPendingJobReasonsHistory来了解为何任务未执行。
另外,在Android 16上还可以通过adb命令强制调整运行时任务配额,以方便测试:
# 取消头部状态配额限制
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS <APP_PACKAGE_NAME>
# 设置等待区
adb shell am set-standby-bucket APP_PACKAGE_NAME active|working_set|frequent|rare|restricted
# 获取所处的等待区状态
adb shell am get-standby-bucket APP_PACKAGE_NAME
用户体验和系统UI
Android 16废弃了无障碍公告(announcement),一种使用announceForAccessibility或者派发TYPE_ANNOUNCEMENT引起的无障碍事件。这些公告会造成Talkback和屏幕发声的混乱,容易被滥用,一些可行的替换方案有:
- 对于像窗口变化之类的极重要的UI变化,可以用Activity.setTitle(CharSequence)和setAccessibilityPaneTitle(java.lang.CharSequence)。在Compose中使用Modifier.semantics { paneTitle = "paneTitle" }。
- 告知用户重要UI变化,使用setAccessibilityLiveRegion(int)。在Compose中,用Modifier.semantics { liveRegion = LiveRegionMode.[Polite|Assertive]}。这些也要小心使用,因为每当View刷新就会触发一个无障碍事件。
- 通知用户有错误,发送一个类型为AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR的无障碍事件,并且设置AccessibilityNodeInfo#setError(CharSequence),或者TextView#setError(CharSequence)。
可以看文档以了解废弃announceForAccessibility的细节以及推荐的替代方案。
适配建议
到目前为止,我们能了解到的Android 16的变化就这么多,总的来看增量变化并不多,新的API 都是一些小的细节上的增强;行为的变更也很少很少,只涉及后台任务和无障碍。新的API不会影响现有的应用,行为变更也不多,可以说对于绝大多数应用来说影响甚微。
现在仍是开发者Preview阶段,只有亲儿子Pixel系列会收到OTA版本,我们了解一下就可以了。即使是应用可能会受到行为变更的影响,也不用着急,建议再等2~3个月,等到有更多的厂商发出Beta版本了,并且API也稳定了时再做适配也不迟。
References
- Features and APIs
- The First Developer Preview of Android 16
- The Second Developer Preview of Android 16
- Behavior changes: Apps targeting Android 16 or higher
- Behavior changes: all apps
欢迎搜索并关注 公众号「稀有猿诉」 获取更多的优质文章!
保护原创,请勿转载!