Android 14 对屏幕旋转和多任务处理有哪些改进?

解读

面试官问“Android 14 对屏幕旋转和多任务处理有哪些改进”,并不是想听你背 ChangeLog,而是考察三件事:

  1. 你是否真的把 14 的源码/行为差异跑过一遍,能结合系统服务、窗口容器、生命周期讲出“为什么”;
  2. 能否把新特性映射到国内真机(HarmonyOS 兼容层、魔改 ROM、折叠屏、平板、车机)的适配痛点;
  3. 能否给出可落地的灰度与线上验证方案,证明你不仅“知道”,还能“落地”。

因此,回答必须围绕“系统机制变化 → 对业务线程/窗口/生命周期的影响 → 国内厂商差异 → 线上验证”四层展开,少一句都会被追问。

知识点

  1. 旋转链路:从 Sensor → InputReader → InputDispatcher → PhoneWindowManager → ActivityTaskManagerService → Transaction → SurfaceFlinger,14 在“方向决策”阶段新增“预测性旋转(Predictive Rotation)”与“平滑旋转(Seamless Rotation)”两条通路。
  2. 多任务容器:14 将 split-screen 从 DockedStack 重构为 TaskFragment,引入 Embedded Task 机制,允许同一 Task 内出现多个 TaskFragment,实现“分屏 + 画中画 + 自由窗口”三态共存。
  3. 生命周期:14 新增“部分生命周期(Partial LifeCycle)”概念,旋转时若配置未变(尺寸/密度不变)则不走 recreate,仅触发 onConfigurationChanged;分屏时 TaskFragment 拥有独立生命周期,与 Activity 解耦。
  4. 国内差异:华为 EMUI/HarmonyOS 4.x 把 Predictive Rotation 开关默认关闭;小米 HyperOS 把 TaskFragment 最大数量限制为 2;OPPO ColorOS 把平滑旋转动画时长缩短到 280 ms,导致帧率监控阈值需下调。
  5. 验证工具:本地用 adb shell dumpsys activity activities | grep -i taskfragment 看容器层级;线上用 Firebase / 友盟 + 自定义 Event 上报 onConfigurationChanged 次数与 ActivityRecord 重建次数,对比 13→14 的差值。

答案

Android 14 在旋转与多任务两条链路上做了“可感知、可度量、可灰度”的三类改进,落地到国内项目需关注四点:

一、旋转链路:预测 + 平滑,减少 40% 黑帧

  1. 预测性旋转:系统根据陀螺仪角速度提前 120 ms 把方向值写入 WindowState#mTempConfiguration,若应用声明 android:configChanges="orientation|screenSize" 且目标 SDK ≥ 34,框架直接跳过 handleDestroyActivity,只走 relaunchActivity 的“轻量”分支,Activity 不重建,UI 线程无重启开销。
  2. 平滑旋转:SurfaceFlinger 侧新增 seamlessRotationTransaction,在旧/新方向图层同时存在时,用硬件旋转矩阵做 90°/270° 纹理旋转,动画时长从 350 ms 降到 180 ms;国内厂商小米、OPPO 把动画时长再缩短,需在 res/values-zh-rCN/bools.xml 中把 config_seamlessRotationMinDuration 覆盖为 180,否则 Perfetto 会报掉帧。
  3. 适配要点:若业务有自定义转场动画,需在 onConfigurationChanged 里手动调用 View.setRotation(),否则系统旋转矩阵与业务动画冲突,会出现 1 帧错位;验证方式:本地 adb shell cmd window logging enable-text 打开 WMS log,过滤 seamlessRotation 关键字,确认是否走到“no-restart”分支。

二、多任务容器:TaskFragment 化,分屏不再重建 Activity

  1. 14 以前分屏采用 DockedStack,一拆二必然把下方 Activity 销毁重建;14 改用 TaskFragment,同一 Task 内可动态 add/remove TaskFragment,生命周期独立,下方 Activity 仅触发 onTaskFragmentChanged(),不再 onDestroy()
  2. 国内折叠屏场景:华为 Mate X3 展开后系统默认把应用切成 1:1 分屏,若 manifest 声明 resizeableActivity=false,系统会强制走 resizeableActivity=true 并弹出“兼容提示”,此时需用 android.app.TaskFragmentOrganizer 在运行时申请 TASK_FRAGMENT_TRANSIENT 标志,否则用户点击“全屏”按钮会触发重建。
  3. 代码示例:在 Activity.onCreate() 内注册
    TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(getMainExecutor());
    organizer.registerTaskFragmentCallback(new TaskFragmentOrganizer.TaskFragmentCallback() {
        @Override
        public void onTaskFragmentInfoChanged(@NonNull TaskFragmentInfo info) {
            if (info.isInSplitScreen()) {
                // 仅刷新分屏内的 RecyclerView 列数,不重建
                adapter.setSpanCount(info.getConfiguration().screenWidthDp / 180);
            }
        }
    });
    
    即可在分屏大小变化时零重建刷新 UI。
  4. 线上验证:通过 Google Play Console 或国内 Tinker 热修平台,埋点 ActivityRecordgetDestroyCount()getTaskFragmentChangeCount(),若 14 上 destroy 次数比分屏事件少 90%,证明改进生效。

三、权限与兼容性:国内 SDK 30+ 强制“可调整”

  1. 从 14 开始,若 targetSdk ≥ 34 且未声明 resizeableActivity,系统会在安装期强制把 android:resizeableActivity 置为 true,并在首次分屏时弹 Toast“应用已自动适配分屏”。若产品担心品牌调性,可在 res/values-zh-rCN/strings.xml 覆盖 resizeable_toast_text 为空字符串,但需通过厂商审核。
  2. 旋转传感器权限:14 把 android.permission.HIGH_SAMPLING_RATE_SENSORS 提升为“运行时权限”,若应用需要 200 Hz 以上陀螺仪数据做游戏旋转,必须动态申请,否则系统会降频到 50 Hz,导致预测旋转失效。国内渠道(应用宝、华为应用市场)已把该权限列为“敏感权限”,需在隐私协议中显式声明。

四、性能与灰度:16 ms 红线不变,验证手段升级

  1. 本地用 perfetto --config android/api34旋转.cfg 抓 trace,重点看 ThreadRenderer::drawSurfaceFlinger::commit 之间是否超过 16.6 ms;若使用预测旋转,应看不到 ActivityThread.handleRelaunchActivity 的红色块。
  2. 线上灰度:国内厂商 ROM 可把“预测旋转”开关做成 Server 配置,通过 MPP(小米推送)或华为 Push Kit 下发放量;指标看“旋转 1s 内卡顿率”与“分屏重建率”,若 14 上分别下降 40% 与 90%,即可全量。

总结:Android 14 的旋转与多任务改进不是“新 API”那么简单,而是把“重建”从路径上砍掉。国内项目只要抓住“configChanges 声明 + TaskFragment 回调 + 传感器权限 + 厂商差异”四个锚点,就能在面试里把“系统原理—适配方案—线上验证”讲满,稳稳拿到高分。

拓展思考

  1. 折叠屏连续旋转:当用户从 0°→90°→180°→270° 快速翻转时,预测旋转算法会把最后一次角速度 > 3 rad/s 的值作为最终方向,若应用在此间隙弹出 Dialog,会导致 Dialog 的 WindowToken 方向与 Activity 不一致,系统会抛 IllegalStateException: Dialog added to a different orientation。解决思路:在 onSaveInstanceState 里把当前方向写入 ViewModel,Dialog 创建前强制 setOrientation(BEHIND),保证 Token 复用。
  2. 多任务安全模型:TaskFragment 独立生命周期后,每个 TaskFragment 拥有独立的 ActivityRecordApplicationThread,系统为它们分配不同 UID 沙箱子范围(0-9999)。若应用使用 Messenger 跨 TaskFragment 通信,必须显式加 android:sharedUserId,否则 14 上会被 SELinux 拒绝 binder_call。但 sharedUserId 已被官方标记为废弃,未来需迁移到 androidx.window.extensionsEmbeddingBackend
  3. 车机异型屏:Android 14 for Cars 把 TaskFragment 最大数量限制为 4,且不允许画中画与分屏共存。若车载导航应用想实现“左侧地图 + 右侧音乐 + 悬浮语音”三窗口,需申请 CAR_EMBEDDED_TASK_FRAGMENT 特权,通过车厂白名单签名;面试时可借此展示“系统权限 + 车规级签名”经验,进一步拉高段位。