MiCarSettings 启动慢 / 白屏 分析报告

  • Appcom.android.car.settings(代码包 com.android.micar.settings,APK /system/priv-app/MiCarSettings/MiCarSettings.apk
  • 版本:versionName 1.2.0.75 / versionCode 2026061601,共享 android.uid.system
  • 数据源:拨杆日志 bugreport bugreport-mach-26.06.18.2.Stable.U.CN-2026-06-26_12-55-54(user 14,pid 11459,uid 1401000)
  • 分析日期:2026-07-07
  • 方法:11 个并行 Agent(时序/白屏/反射/任务框架/ANR-Jank/系统压力/dumpsys/慢binder/线程栈锁/非binder阻塞/渲染管线)+ CPU/温度分析 + 源码走读

一、TL;DR(先看结论)

  1. 这是驾驶员切换(user 12 → user 14)触发的新用户冷启动,不是被杀重启(无 LMK、内存/IO 无压力)。
  2. 用户感知的**“白屏 ~6s”主体在系统侧**:用户切换流程拉起 30+ 进程 + WM 主动冻屏死等真 Launcher(CarLauncherActivity) idle。App 改不动。
  3. 用户感知的**“启动慢/卡顿 1675ms”主体在 App 侧**:Settings_Launcher_Homepage 首帧主线程被**同步批量注册 44 个 CarProperty callback(893ms binder)**占住(FrameTimeline 实测 97% 卡在此),叠加蓝牙初始化 188ms、AM binder 528ms。
  4. 环境放大器:CPU 95°C 触发 thermal level-3,大核砍 17%,解释”为什么这次特别慢”。
  5. 病根一行代码CarPropertyCacheManager.java:192 在主线程同步 carPropertyManager.registerCallback(...)。历史 09:06 ANR 显示同一同步 binder 模式曾造成 50 秒级卡死

二、启动了几次(全文只有 1 次进程冷启)

#事件时间耗时/说明行号
user12 旧进程 7515 温启(DeeplinkActivity)12:53:37.935+101ms,正常31072
user12 7515 Settings_Launcher_Homepage12:55:04.491545ms,正常56725
1Start proc 11459 (u14) — 唯一进程派生12:55:38.050FallbackHome(HOME),caller=null71563
1aFallbackHome Displayed12:55:40.685+876ms82085
2Settings_Launcher_Homepage (u14 首次)12:55:44.225→45.872+1675ms ← 慢+白屏101967
user12 旧进程 7515 被杀12:55:45.309”stop user 12 due to finish user”(非 LMK99094

历史埋点正常启动是 545/563/584ms,本次撞到 1675ms。慢的就是 user14 这次。procstats 显示该进程非常驻、每次 user-switch 被 stop user 杀,累计运行 2h45m —— 驾驶员切换是本 App 启动的常态入口,问题高频复现


三、完整时间线

时刻事件归责
37.606用户切换,WM 开始冻屏 mClientFreezingScreen=true系统
38.013START FallbackHome (HOME intent)系统
38.050Start proc 11459系统
38.253→38.500Application.onCreate,MainThreadStartTask 247ms 主线程阻塞App
38.863FallbackHome 首帧(Displayed +876ms)App
38→4330+ user14 进程并发冷启动,user-switch 流程(UserSwitchTracker 4 步 700-1000ms)系统
42.485CarLauncherActivity idle,WM 解冻(冻屏 4.88s)系统
44.225START Settings_Launcher_Homepage(SystemUI 发 launcher intent)系统
44.302→44.542HomepageActivity onCreate 240ms(TopLevelMenuFragment 充气 + 28 层主题继承链)App
44.920→45.813批量注册 44 个 CarProperty callback 893ms ← 白屏卡顿直接元凶App
45.530IActivityManager code=30 同步 528ms(AMS 远端锁竞争)系统
45.805 / 45.818Choreographer Skipped 52 frames / Davey! 891msApp
45.872Displayed Settings_Launcher_Homepage +1675msApp
全程CPU 88→95°C / thermal level-3 / 大核 -17% / SOCCP 86%放大器

四、根因分层

A. 系统侧 —— 白屏时长主体(~6s,App 难控)

  • WM 主动冻屏 mClientFreezingScreen=true,MiCar 钩子 UserControllerImpl.onLauncherReady 死等真 Launcher(CarLauncherActivity) idle 才解冻 → 4.88s(37.606→42.485);HOME 类 Activity 无 splash/snapshot → 纯白
  • user-switch 流程:30+ 个 user14 进程并发冷启动,UserSwitchTracker 4 步 700–1000ms,WallpaperManagerService observer 803ms,system_server 多处 Slow delivery 100–205ms,zygote fork 排队
  • SystemUI 直到 user-switch-complete 才发 Settings 的 launcher intent → Settings 的 START 比进程创建晚了 ~6s

B. App 自身 —— 卡顿/首帧慢(可优化,重点)

首帧 891ms 中 864.6ms(97%)卡在主线程 Traversal(PerformTraversals→DrawStart),与 CarProperty 同步 binder 阻塞期(893ms)完全重叠(FrameTimeline 实证)。GPU 仅 12.4ms,Sync 0.17ms,布局 DisplayList 1.9ms —— 与 GPU/布局复杂度无关,纯主线程 binder 阻塞

C. 环境放大器 —— 解释”为什么这次特别慢”

  • CPU 核心温度 88→95°C(thermal_zone17 峰值 95°C),ThermalPolicyGenerator: level=3, temp=95
  • 大核 Cluster7: 3302MHz → 2745MHz(-17%),SOCCP 86%,PSI cpu ~50%,loadavg 17-19
  • 内存/IO 无压力(MemAvail 11.5GB / 23.6GB,PSI mem 0.08% / io ~3%)

五、主线程阻塞全貌(1675ms 构成)

Binder 类 ≈ 1338ms(80%)

调用耗时行号对端/性质
CarProperty 批量注册(44 个 callback)893ms101538CarService→vehicle HAL,App 能治本
IActivityManager code=30528ms100015system_server AMS,远端锁竞争
IActivityManager code=37230ms96354同上 AMS
IInputMethodManager code=9215ms103681system_server IMMS,IME 锁

已排除(不在主线程 tid=11459):子线程 tid=4270 的 AM 756ms、相机进程的 622/1002/1012ms。无本地 binder 锁死(无 lockContention / DeadObjectException 在主线程)。

非 Binder 类 ≈ 363ms

类别耗时行号
蓝牙 LocalBluetoothManager 同步初始化(含反射 CNFE)188ms72309-73148
TopLevelMenuFragment onCreate 静默期(Controller 初始化)118ms94336-94660
HvacAppSeatEntranceController 等初始化(部分 binder)231ms94915-96386
主题继承链 InheritanceMap 解析(28 层)19ms94177
TopLevelMenuFragment 充气38ms94662-94708

明确否定项(这些都没问题)

主线程同步 SharedPreferences 写、SQLite/DB、文件 IO、其它反射、post 到主线程的耗时 Runnable、Looper Slow delivery(App 进程)、StrictMode、BlockMonitor —— 全部未发现

线程栈(VM TRACE @ 12:56:12):0 BLOCKED、0 waiting-to-lock、无死锁,binder 线程池 6 个全空闲未打满。


六、源码级根因(精确到行)

病根一行base/settingsVehicleLib/src/main/java/com/android/car/settings/miauto/vehicle/CarPropertyCacheManager.java:192

carPropertyManager.registerCallback(mInternalCarPropertyEventCallback, propertyId,
        CarPropertyManager.SENSOR_RATE_ONCHANGE);  // ← 同步 binder,被卡在主线程

Activity 阶段 44 个(893ms 白屏元凶)

Settings_Launcher_Homepage → HomepageActivity → BaseCarSettingsActivity.onCreate(:149)
 → VehicleControlSettingsFragment (XML 里 28 个 controller)
 → Fragment.onCreate → PreferenceController.onCreate(:401) 【全主线程,无 post】
 → CarPropertyMgrPreferenceController.onPostCreateInternal(:521)
 → setCarManagerCallback → NewBaseCarServiceManager.registerCarServiceListener(:71)
 → isConnected()==true ★同步回调★ onPropertyManagerPrepared
 → registerPropertyCallback → 44 个 propId × registerCallback(:192) 同步 binder

放大点:NewBaseCarServiceManager.java:71-76 在 Car 服务已连接时同步直调回调(没有 post),28 个 controller 的注册全挤在 Fragment.onCreate 主线程。

Application 阶段 68 个(31ms)

MainThreadStartTask.java:62,66VehiclePermanentListener.init()registerPropertyCallback(~68 个 propId),同一 binder 链。

历史关联(09:06 ANR,更严重)

VM TRACES AT LAST ANR(行 368627+)记录 09:06:42 system_server watchdog ANR,binder 卡链:

car.settings(pid 11268):ThreadPoolUtils → car.core.server(15723) → system_server(4204) → pid 944
同步卡 50.885s(链底 pid 944 code 17 卡 50.212s)→ 触发 watchdog

→ 同一”主线程/worker 同步发起 car binder”模式,历史上造成过 50 秒级卡死,不只是本次 893ms。


七、源码级优化方案(按性价比)

方案改动收益风险
A 治本CarPropertyCacheManager.registerPropertyCallback(:192)registerCallback 扔到单线程 executor;unregister 同切;callback dispatch 处加 runOnUiThread 切回主线程App 31ms→3ms、Activity 893ms→~30ms中:确认 onChangeEvent 回调线程语义
B 体验兜底CarPropertyMgrPreferenceController.onPostCreateInternal(:521)setCarManagerCallback(this)DecorView.post{},推迟到首帧后Displayed 1675ms→~500ms,Davey/丢帧立刻消失低:首帧用 Application 阶段 cache 兜底,binder 完成后 onChangeEvent 自然刷新
CMainThreadStartTask:62-67VehiclePermanentListener.init() 挪进已有的 initInAsync();蓝牙 getLocalBtManager(188ms)/HotspotUtils(22ms) 同挪主线程再省 ~240ms低-中:回归车控项可见性(CarConfigManager lazy 兜底)
DLogHelper.kt:33mHandler.post 改主线程同步 append修日志保真([Delay] 时间戳失真)
EBroadcastSourceInfoHandler 反射(settingslib 裁剪遗留,每次启动 CNFE 4ms+日志噪声);修 application onCreate finish : 14 埋点 bug代码卫生

推荐落地顺序:A(治本,所有新 Controller 自动受益)+ B(消白屏/Davey)+ C(蓝牙/车控挪异步)。三刀下去 App 主线程阻塞从 ~1.2s 压到 <100ms,Displayed 从 1675ms 降到 ~400-500ms

⚠️ 方案 A 注意:registerCallback 走子线程后,onChangeEvent 落在 CarService binder 接收线程,业务 callback(CarPropertyMgrPreferenceController.onPropertyChanged:346)若假设主线程,需在 dispatch 处统一 runOnUiThread

系统侧(需推 SystemUI/WM 团队,App 动不了)

  • 审查 UserControllerImpl$LocalService.onLauncherReady 钩子,能否在 CarLauncherActivity onResume/首帧 drawn 时就解冻,而非死等 idle(省 ~1.3s)
  • HOME 类 Activity 启用 TaskSnapshot 回放(type=1),冻屏期显示上次桌面快照避免纯白
  • 优化 CarLauncherActivity 从 BG 拉起到 idle 的 1.3s
  • 减少 user-switch 时 30+ 进程并发抢 AMS 锁(缓解 528ms AM binder)

八、关键行号索引(bugreport)

内容行号
Start proc 1145971563
Application.onCreate 入口72098
68 个 CarProperty 注册(主线程)72143-72297
蓝牙 getLocalBtManager 起/止72309 / 73148
BroadcastSourceInfoHandler CNFE72335-72361
MainThreadStartTask finish73201
FallbackHome Displayed +876ms82085
WM 冻屏开始/解除71151 / 86123
START Settings_Launcher_Homepage93833
主题继承链 InheritanceMap94177
44 个 CarProperty 批量注册 893ms101538
AM code=30 528ms100015
Choreographer Skipped 52 frames101489
Davey! 891ms(FrameTimeline)101565
Displayed Settings_Launcher_Homepage +1675ms101967
CPU 95°C / thermal level=393853 / 94232
MiCarPerfService CpuInfo SOCCP 86%93925
thermalservice dump822083
gfxinfo pid 11459628104
VM TRACE pid 11459(主线程空闲)311384-312815
VM TRACES AT LAST ANR(50s binder 卡链)368627 / 387931-387976

九、源码文件索引

文件作用
base/settingsVehicleLib/.../vehicle/CarPropertyCacheManager.java:192病根:主线程同步 registerCallback
base/settingsVehicleLib/.../common/CarPropertyMgrPreferenceController.java:521方案 B 改点(onPostCreateInternal)
app/.../miauto/MainThreadStartTask.java:62,66,193-212方案 C 改点(init/蓝牙/热点)
base/settingsBaseLib/.../appstart/AppStartTaskDispatcher.java启动调度器(CountDownLatch.await 1000ms)
base/settingsBaseLib/.../uitls/LogHelper.kt:33方案 D 改点
settingsPage/VehicleBodyControl/.../miauto_vehicle_body_ctrl_settings_fragment.xml28 个 controller 的 Fragment