首页 / 资讯中心 / 文章详情

从一份 logcat 看懂 B 站冷启动:红米手机上的完整启动链路解析

从一份 logcat 看懂 B 站冷启动:红米手机上的完整启动链路解析 ★ FEATURED ARTICLE
从一份 logcat 看懂 B 站冷启动红米手机上的完整启动链路解析本文基于一台红米手机设备代号rodinHyperOS联发科平台上抓取的真实 logcat逐步还原哔哩哔哩tv.danmaku.bili从进程不存在到首帧上屏、再到各子进程拉起的完整过程。每个阶段都附上原始日志与对应分析可作为 Android 应用启动分析的参考样例。一、测试背景与日志说明设备红米手机代号rodinHyperOSMIUI 系MTK 平台屏幕 1220×2712density 520。应用哔哩哔哩tv.danmaku.biliuid 10294targetSdkVersion 35。触发方式通过 Monkey 发起 Launcher 启动相当于自动化点击桌面图标。日志范围本次启动发生在20:03:46 ~ 20:04:02恰好完整落在 main/system buffer 保留窗口内因此进程、Application、Activity 的细节日志都在。为什么能确定是冷启动两条证据当天下午 15:52B 站所有进程被上滑清理杀光此后再无启动记录直到本次启动10-24 15:52:09.535 1883 2003 I am_kill : [0,19408,tv.danmaku.bili:ijkservice,400,stop tv.danmaku.bili due to SwipeUpClean,178428] 10-24 15:52:09.540 1883 2003 I am_kill : [0,10726,tv.danmaku.bili:web,400,stop tv.danmaku.bili due to SwipeUpClean,424060] 10-24 15:52:09.544 1883 2003 I am_kill : [0,26320,tv.danmaku.bili:download,0,stop tv.danmaku.bili due to SwipeUpClean,152848] 10-24 15:52:09.548 1883 2003 I am_kill : [0,28355,tv.danmaku.bili,50,stop tv.danmaku.bili due to SwipeUpClean,756636]启动后 B 站自己的埋点也明确上报了冷启动10-24 20:03:47.844 16138 16138 E DurationManager: dau reportForeground, isColdStart: true, ascribeCallback: com.bilibili.gripper.container.dau.c$b484c07c二、启动全流程总览Monkey(shell) 发起 MAIN/LAUNCHER Intent ↓ ATMS/ActivityStarter新建 task#316、冷启动加速、暂停 Launcher、显示 Splash 启动窗 ↓ AMS → Zygote fork 主进程 16138am_proc_start ↓ attachApplicationam_proc_bound→ ActivityThread/ClassLoader 初始化 ↓ ContentProvider 安装 Application 初始化B站 Gripper 框架分段并行 ↓ MainActivityV2 onCreate(198ms) → onStart(11ms) → onResume(9ms) ↓ 首帧绘制 → Displayed 822ms → 移除 Splash → 获得输入焦点 ↓ 首屏后按需拉起子进程ijkservice → download → webview sandbox → :web(小程序)三、逐阶段日志解析1. 启动触发Monkey 代替手指点击图标10-24 20:03:46.695 9494 9494 W Monkey : args: [-p, tv.danmaku.bili, -c, android.intent.category.LAUNCHER, 1] 10-24 20:03:47.025 1883 2942 I ActivityTaskManager: setActivityController mControllerandroid.app.IActivityController$Stub$Proxycfa0ecc, imAMonkeytrue, CallingPid9494 CallingUid2000 10-24 20:03:47.104 1883 2644 I ActivityTaskManager: START u0 {actandroid.intent.action.MAIN cat[android.intent.category.LAUNCHER] flg0x10200000 cmptv.danmaku.bili/.MainActivityV2} with LAUNCH_SINGLE_TOP from uid 2000 from pid 9494 callingPackage com.android.shell (BAL_ALLOW_PERMISSION) result code0分析Monkeypid 9494shell uid 2000向 system_serverpid 1883发起MAIN LAUNCHER启动请求目标组件是tv.danmaku.bili/.MainActivityV2——这就是 B 站桌面入口 Activity。result code0表示启动请求被接受。注意 flag0x10200000FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED是标准的桌面启动组合。2. AMS 调度新建 Task、冷启动加速、准备启动窗10-24 20:03:47.085 1883 2644 I ActivityStarterImpl: boost cold start activity for tv.danmaku.bili 10-24 20:03:47.088 1883 2644 I wm_task_created: 316 10-24 20:03:47.097 1883 2644 I wm_create_activity: [0,144739032,316,tv.danmaku.bili/.MainActivityV2,android.intent.action.MAIN,NULL,NULL,270532608] 10-24 20:03:47.098 1883 2644 I wm_pause_activity: [0,216153653,com.miui.home/.launcher.Launcher,userLeavingtrue,pauseBackTasks] 10-24 20:03:47.097 1883 2644 I WindowManager: Try to add startingWindow type STARTING_WINDOW_TYPE_SPLASH_SCREEN this ActivityRecord{144739032 u0 tv.danmaku.bili/.MainActivityV2 t316} ... 10-24 20:03:47.098 1883 2231 D PreStartingManager: Get background color: fff8f8f8 key: tv.danmaku.bili_night containColor: true 10-24 20:03:47.122 1883 2231 D PreStartingManager: The real or pre StartingWindow has been displayed. pkg: tv.danmaku.bili分析HyperOS 识别到冷启动执行boost cold startCPU/IO 等加速策略。为 B 站新建task#316并创建 MainActivityV2 的 ActivityRecord。旧前台com.miui.home桌面进入 pause。在应用进程还没创建之前系统先贴出Splash 启动窗背景色fff8f8f8避免点击后白屏/无响应的体感。这一步是系统做的不依赖应用任何代码。3. 进程创建Zygote fork 与 attach 绑定10-24 20:03:47.131 1883 1988 I am_proc_start: [0,16138,10294,tv.danmaku.bili,next-top-activity,{tv.danmaku.bili/tv.danmaku.bili.MainActivityV2}] 10-24 20:03:47.132 1883 1988 I ActivityManager: Start proc 16138:tv.danmaku.bili/u0a294 for next-top-activity {tv.danmaku.bili/tv.danmaku.bili.MainActivityV2} callercom.android.shell 10-24 20:03:47.132 16138 16138 E Zygote : process_name_ptr:16138 tv.danmaku.bili 10-24 20:03:47.133 16138 16138 E Zygote : SetMemoryProtected process_name_ptr:16138 tv.danmaku.bili 10-24 20:03:47.137 16138 16138 I tv.danmaku.bili: Using CollectorTypeCC GC. 10-24 20:03:47.140 16138 16138 E tv.danmaku.bili: Not starting debugger since process cannot load the jdwp agent. 10-24 20:03:47.150 1883 3057 I am_proc_bound: [0,16138,tv.danmaku.bili] 10-24 20:03:47.159 16138 9529 D nativeloader: Configuring clns-10 for other apk ... target_sdk_version35 ... library_path/data/app/~~random/tv.danmaku.bili-random/lib/arm64:...分析am_proc_start的 hosting type 是next-top-activity即为了即将置顶显示的 Activity 而创建进程是冷启动的典型标志。AMS 通过 Zygote fork 出 pid16138新进程立刻设置进程名、GC 类型CC 并发拷贝回收release 包不加载 jdwp 调试代理属正常日志。仅19ms后47.131→47.150进程完成attachApplicationam_proc_bound表示进程与 AMS 绑定成功随后进入 ActivityThread 初始化配置 ClassLoader/native 库路径targetSdk 35、HWUI 渲染环境等。4. Application 初始化B 站 Gripper 启动框架全程最重的阶段bind 之后到 Activity 创建之前应用要完成自己的 Application 初始化。B 站使用自研的Gripper启动框架把初始化任务拆成attach和onCreate等阶段并用协程线程池DefaultDispatcher-worker-N并行执行10-24 20:03:47.219 16138 16138 W tv.danmaku.bili: Unsupported class loader: java.lang.Classcom.bilibili.lib.tribe.core.internal.loader.DefaultClassLoaderService$PathRootClassLoader 10-24 20:03:47.430 16138 16138 I FastTriggerStrategy: [main] direTrigger: boot_opt_attach_seg 10-24 20:03:47.430 16138 9557 I FastTriggerStrategy: [DefaultDispatcher-worker-6] trigger: preOnAttach 10-24 20:03:47.430 16138 9555 I FastTriggerStrategy: [DefaultDispatcher-worker-4] trigger: OnAttach 10-24 20:03:47.444 16138 16138 I GripperExecute: direAsyncTrigger boot_opt_onCreate_seg 0 10-24 20:03:47.445 16138 16138 I GripperExecute: [main] onOnContentProviderAttachInfo: com.bilibili.gripper.AppInitProvider1cd59bf 10-24 20:03:47.445 16138 16138 I GripperExecute: [main] onOnContentProviderAttachInfo: com.huawei.hms.aaid.InitProvider2f5b178 10-24 20:03:47.446 16138 16138 I GripperExecute: [main] onOnContentProviderAttachInfo: com.bilibili.lib.downloader.p2p.P2PProvider15f28cb 10-24 20:03:47.553 16138 16138 I GripperExecute: awaitTrigger boot_opt_onCreate_seg 55与此同时若干基础组件在做预加载例如配置中心与闪屏开屏资源10-24 20:03:47.279 16138 9552 I DDLib : [DefaultDispatcher-worker-1] preloadProdData:execute start 10-24 20:03:47.326 16138 9552 I DDLib : [DefaultDispatcher-worker-1] execute DataCenter preloadProdData cost 52 ms 10-24 20:03:47.318 16138 9554 I StartupOptimize: Splash image preloaded successfully 10-24 20:03:47.377 16138 9553 I SplashListResponseKit: readSplashListResponseFromDisk 111分析tribe是 B 站的插件化/类加载组件自定义 ClassLoader 在 Application 最早期就介入。大量 ContentProvider 在attachBaseContext之后被系统自动安装AppInitProvider、华为 HMS、P2P、免流、下载等这是冷启动隐藏的耗时来源之一。Gripper 的关键分段点boot_opt_attach_segApplication.attach→preOnAttach/OnAttach并行任务→boot_opt_onCreate_segApplication.onCreateawaitTrigger ... 55表示主线程等待 onCreate 段并行任务收尾约 55ms。这一大段47.150 绑定 → 47.574 Activity 开始初始化约 424ms占整个启动耗时的一半以上是冷启动优化最值得关注的部分。5. MainActivityV2 生命周期onCreate → onStart → onResume10-24 20:03:47.574 16138 16138 I GripperExecute: onActivityInit: tv.danmaku.bili.MainActivityV2 10-24 20:03:47.740 16138 16138 I GripperExecute: direTrigger boot_opt_main_bk 121 10-24 20:03:47.762 16138 16138 I SplashListResponseKit: getSplashListResponse 0 10-24 20:03:47.784 16138 16138 I wm_on_create_called: [0,144739032,tv.danmaku.bili.MainActivityV2,performCreate,198] 10-24 20:03:47.796 16138 16138 I wm_on_start_called: [0,144739032,tv.danmaku.bili.MainActivityV2,handleStartActivity,11] 10-24 20:03:47.806 16138 16138 I wm_on_resume_called: [0,144739032,tv.danmaku.bili.MainActivityV2,RESUME_ACTIVITY,9] 10-24 20:03:47.837 16138 16138 I wm_on_top_resumed_gained_called: [144739032,tv.danmaku.bili.MainActivityV2,topStateChangedWhenResumed]分析performCreate 198MainActivityV2 的 onCreate 耗时198ms其中 B 站自己的boot_opt_main_bk段就占121ms首页/主界面业务初始化。onStart 11ms、onResume 9ms都很轻。期间读取闪屏配置getSplashListResponse与前面预加载的开屏资源呼应。wm_on_*_called系列是系统 events buffer 的生命周期打点最后一个数字就是耗时ms做启动分解时非常好用。6. 首帧上屏Displayed 822msSplash 退场10-24 20:03:47.892 1883 1970 I WindowManager: onFirstWindowDrawn, try to remove startingWindow. ar: ActivityRecord{144739032 u0 tv.danmaku.bili/.MainActivityV2 t316} ... 10-24 20:03:47.902 1883 1928 I wm_activity_launch_time: [0,144739032,tv.danmaku.bili/.MainActivityV2,822] 10-24 20:03:47.906 1883 1928 I ActivityTaskManager: Displayed tv.danmaku.bili/.MainActivityV2 for user 0: 822ms 10-24 20:03:48.059 1883 1970 I WindowManager: StartingWindow exit animation finished, win Window{2ba5538 u0 Splash Screen tv.danmaku.bili EXITING} remove true 10-24 20:03:48.222 16138 16138 I input_focus: handleWindowFocusChanged:tv.danmaku.bili/tv.danmaku.bili.MainActivityV2 mView:com.android.internal.policy.DecorView{16b0a2d V.E...... R.....ID 0,0-1220,27...}分析47.892 应用首帧绘制完成系统开始移除 Splashwm_activity_launch_time给出官方口径启动耗时822ms从 startActivity 到首帧。Splash 退出动画在 48.059 结束48.222 窗口获得输入焦点至此启动流程在系统层面闭环。注意Displayed 只代表第一帧画出来了不代表首页数据加载完成、可流畅交互。完全绘制应看reportFullyDrawn本日志未出现。7. 首屏之后四大子进程陆续拉起B 站是多进程架构首帧之后各业务按需拉起独立进程10-24 20:03:48.229 1883 1988 I am_proc_start: [0,10109,10294,tv.danmaku.bili:ijkservice,service,{tv.danmaku.bili/tv.danmaku.ijk.media.player.services.IjkMediaPlayerRemoteService}] 10-24 20:03:49.349 1883 1988 I am_proc_start: [0,10576,10294,tv.danmaku.bili:download,service,{tv.danmaku.bili/com.bilibili.game.service.DownloadService}] 10-24 20:03:53.690 1883 1988 I am_proc_start: [0,10821,99150,com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0,,{tv.danmaku.bili/org.chromium.content.app.SandboxedProcessService0:0}] 10-24 20:03:57.845 1883 1988 I am_proc_start: [0,10967,10294,tv.danmaku.bili:web,service,{tv.danmaku.bili/com.bilibili.lib.fasthybrid.SmallAppService}] 10-24 20:04:02.289 1883 1988 I am_proc_start: [0,11261,99151,com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:1,,{tv.danmaku.bili/org.chromium.content.app.SandboxedProcessService0:1}]分析时间进程作用首帧 0.3s:ijkserviceijkplayer 播放器独立进程隔离播放崩溃/内存首帧 1.4s:download游戏下载服务首帧 5.8sWebView 沙箱进程 :0Chromium 渲染进程WebView 初始化首帧 9.9s:webfasthybrid 小程序容器SmallAppService首帧 14.4sWebView 沙箱进程 :1第二个渲染进程这些进程都由service或 WebView 触发而不是启动主链路必需体现了主进程先出首帧重业务后置的策略但同时也意味着启动后十几秒内系统仍有持续的进程创建开销。四、822ms 都花在哪了以系统Displayed口径20:03:47.084 → 47.906拆解阶段时间段耗时约占比AMS 调度/建 Task/Splash47.084 → 47.13147ms6%Zygote fork attach 绑定47.131 → 47.15019ms2%Application 初始化Provider Gripper47.150 → 47.574424ms52%Activity onCreate/onStart/onResume47.574 → 47.806232msonCreate 198ms其中业务段 121ms28%首帧绘制与上屏47.806 → 47.906100ms12%结论与观察Application 初始化是冷启动最大头超过一半。B 站已经用了 Gripper 分段 协程并行 数据预加载来压缩它但 Provider 数量、并行任务收尾等待await 55ms仍是可观开销。Activity 侧耗时集中在boot_opt_main_bk121ms的首页业务初始化。系统侧开销fork、调度、启动窗合计不到 70ms优化空间主要在应用自身。若要做完整体验评估还需补充reportFullyDrawn、首页接口耗时与帧率数据822ms 只是首帧而非可用。五、附日志抓取步骤手工复现不用脚本直接手工执行。开两个 CMD 窗口窗口 1 — 抓取应用启动流程日志adb logcat -c adb logcat -b all -v threadtime D:\download\logcat.txt光标会停在这里等待输出先不要动。窗口 2 — 冷启动哔哩哔哩adb shell am force-stop tv.danmaku.bili timeout /t 2 adb shell monkey -p tv.danmaku.bili -c android.intent.category.LAUNCHER 1等手机上哔哩哔哩完全打开开屏广告放完、首页刷出来约 20~30 秒。回到窗口 1 — 停止抓取Ctrl C窗口 2 — 抓内核日志adb shell dmesg D:\download\kernel.txt说明adb logcat -c先清空环形缓冲区保证抓到的基本是本次启动的日志-b all同时抓 main/system/events/radio 等所有 buffer-v threadtime输出带日期、时间、PID/TID 的格式即本文分析所用格式。force-stop确保是冷启动monkey -c LAUNCHER 1模拟点击桌面图标。若 logcat.txt 是 UTF-16 编码分析前需先转成 UTF-8由于手机没有root权限无法抓取在抓取日志的报了Permission denied错误要抓取内核得有root权限所有分析的日志都是红米系统日志没有内核的日志。六、附本次分析用到的检索命令在日志检索过滤可用到这些日志一个是在Linux环境中另外是在windows环境中下图是过滤后的样子# Linux环境中# 进程创建/绑定/查杀grep-nEam_proc_start|am_proc_bound|am_killlogcat.txt|grepbili# Activity 启动请求与首帧耗时grep-nESTART u0|wm_activity_launch_time|Displayedlogcat.txt|grepbili# Activity 生命周期耗时grep-nEwm_on_(create|start|resume)_calledlogcat.txt|grepMainActivityV2# B站 Gripper 启动框架分段打点grep-nEFastTriggerStrategy|GripperExecute|GripperTimelogcat.txt# 主进程主线程行为pid 换成实际的grep-E 16138 16138 logcat.txt# --------------------------------------------# windows环境中# 进程创建/绑定/查杀findstr /n /i /c:am_proc_start/c:am_proc_bound/c:am_killlogcat.txt|findstr /ibili# Activity 启动请求与首帧耗时findstr /n /i /c:START u0/c:wm_activity_launch_time/c:Displayedlogcat.txt|findstr /ibili# Activity 生命周期耗时findstr /n /i /c:wm_on_create_called/c:wm_on_start_called/c:wm_on_resume_calledlogcat.txt|findstr /iMainActivityV2# B 站 Gripper 启动框架分段打点findstr /n /i /c:FastTriggerStrategy/c:GripperExecute/c:GripperTimelogcat.txt# 主进程主线程行为PID 换成实际的findstr /n /c: 16138 16138 logcat.txt日志来源红米 rodin / HyperOS2026-10-24 20:03:46 ~ 20:04:02全文日志均为原始抓取内容对超长行做了截断。
阅读完成 · 觉得有帮助?
咨询建站