系统app调试之 Dumpsys 调试信息解析
平时我们都是使用dumpsys来输出某个服务的相关信息,比如dumpsys SurfaceFlinger,dumpsys window windows等。
这些其实都是系统的service情况信息输出,但是大家是否有想过我们普通的app想要进行dump应该如何呢?比如我想要在查看调试自己写的Activity相关的信息如何查看呢?
这个就是我们今天要来分享的一个dump app的相关相关信息方式。
dump命令使用
命令格式
Activity的dump方式
dumpsys activity xxxx(Activity类名)
这里的xxxx最好写出全类名。

Service的dump方式
比如要dump Launcher的某个service那么格式如下:
adb shell dumpsys activity service xxx(某个Service名字) 案例:
adb shell dumpsys activity service TouchInteractionService
或者
adb shell dumpsys activity service com.android.launcher3/com.android.quickstep.TouchInteractionService
这些Activity名字和Service名字哪里获取呢?
可以使用dumpsys package xxx包名。
比如桌面有哪些Activity和Service
adb shell dumpsys package com.android.launcher3

本文基于 adb shell dumpsys activity QuickstepLauncher 命令的输出,结合 AOSP16-r4 Launcher3 源码,逐段解析每个 dump 信息的作用和调试价值。
1. Activity 生命周期与状态 (ActivityRecord)
TASK null id=23 userId=0 displayId=0(type=INTERNAL)
ACTIVITY com.android.launcher3/.uioverrides.QuickstepLauncher 5bb04f pid=1382 userId=0 uid=10122 displayId=0(type=INTERNAL)
Local Activity 869e2cf State:
mResumed=true mStopped=false mFinished=false
mIsInMultiWindowMode=false mIsInPictureInPictureMode=false
mChangingConfigurations=false
mCurrentConfig={1.0 310mcc260mnc [en_US] ldltr sw360dp w360dp h640dp 480dpi nrml long compactNeeded port ...}
mLoadersStarted=true
来源:Android 框架层 ActivityRecord.dump()(系统侧 dump,非 Launcher 自己控制)。
各字段含义:
TASK null id=23 | null 表示没有关联的 Task 对象引用 | |
userId=0 | ||
displayId=0 | ||
pid=1382 | ||
uid=10122 | ||
mResumed=true | ||
mStopped=false | onStop() | |
mFinished=false | ||
mIsInMultiWindowMode=false | ||
mIsInPictureInPictureMode=false | ||
mChangingConfigurations=false | ||
mCurrentConfig | ||
mLoadersStarted=true |
调试价值:这是第一个要看的区域。如果 Launcher 行为异常,先确认它是否处于预期生命周期状态。
相关源码:
// QuickstepLauncher.java 继承自 Launcher extends BaseActivity
// 生命周期回调在 Launcher.java 中:
// onResume() -> onPause() -> onStop() -> onDestroy()
// 以及 onActivityFlagsChanged() 处理状态标志变化
2. ViewRoot 渲染系统
其实这部分数据就是把我们熟悉的ViewRootImpl.java相关的数据进行输出。
ViewRoot:
mAdded=true mRemoved=false mStopped=false
mPausedForTransition=false
mConsumeBatchedInputScheduled=false
mPendingInputEventCount=0
mTraversalScheduled=false
mReportNextDraw=false
来源:ViewRootImpl.dump(),是每个 Window 的顶层渲染管理器。
各字段含义:
mAdded=true | ||
mRemoved=false | ||
mStopped=false | ||
mPausedForTransition=false | ||
mPendingInputEventCount=0 | ||
mTraversalScheduled=false | ||
mReportNextDraw=false |
调试价值:用于诊断 UI 渲染问题。如果 mTraversalScheduled=true 且长时间不变, 说明可能发生了 measure/layout 死循环或阻塞。
相关源码:
// QuickstepLauncher.java: onCreate()
getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
// PRIVATE_FLAG_OPTIMIZE_MEASURE 优化 measure 过程,减少过度测量
2.1 app层收到事件处理理
android.view.ViewRootImpl$NativePreImeInputStage: mQueueLength=0
android.view.ViewRootImpl$ImeInputStage: mQueueLength=0
android.view.ViewRootImpl$NativePostImeInputStage: mQueueLength=0
含义:三阶段输入管道队列长度均为 0,说明当前没有积压的输入事件。
2.2 Configuration 报告
mLastReportedMergedConfiguration={mGlobalConfig=... mOverrideConfig=...}
mLastConfigurationFromResources={...}
含义:最后一次报告的全局配置与 Override 配置。mOverrideConfig 中mActivityType=home 表示这是 Home Activity。
3. InsetsController — 窗口边距
InsetsController:
mDisplayFrame=Rect(0, 0 - 1080, 1920)
InsetsSource id=d1660001 type=navigationBars frame=[0,1848][1080,1920] visible=true
InsetsSource id=d6d50000 type=statusBars frame=[0,0][1080,72] visible=true
InsetsSource id=3 type=ime frame=[0,0][0,0] visible=false
来源:InsetsController.dump(),管理系统栏(状态栏、导航栏、输入法)对窗口的边距影响。
关键条目解读:
navigationBars [0,1848][1080,1920] | |
systemGestures [0,0][90,1920] | |
systemGestures [990,0][1080,1920] | |
statusBars [0,0][1080,72] | |
mandatorySystemGestures [0,1824][1080,1920] | |
ime frame=[0,0][0,0] visible=false |
调试价值:
确认设备是手势导航还是三键导航(有 systemGestures区域 = 手势导航)排查内容被系统栏遮挡的问题 确认 IME 弹出/收起状态
4. View Hierarchy — 视图树(最核心)
平时要看View的层级都是需要通过布局抓取工具等来查看,那么这个dump方式也算是最简单的方式来获取。
com.android.internal.policy.DecorView{9104c85}[QuickstepLauncher]
android.widget.LinearLayout
android.widget.FrameLayout #1020002 android:id/content
com.android.launcher3.LauncherRootView #7f0901e3 app:id/launcher
com.android.launcher3.dragndrop.DragLayer #7f090144 app:id/drag_layer
com.android.launcher3.views.AccessibilityActionsView
com.android.launcher3.Workspace #7f090409 app:id/workspace
com.android.launcher3.CellLayout
ShortcutAndWidgetContainer
QsbContainerView #7f0902ef app:id/search_container_workspace
...
com.android.launcher3.Hotseat #7f0901b4 app:id/hotseat
DoubleShadowBubbleTextView (4 icons)
PageIndicator (page_indicator_container)
DropTargetBar #7f090146 (drop_target_bar)
ScrimView #7f0902dd (scrim_view)
LauncherRecentsView #7f090282 (overview_panel)
OverviewActionsView #7f090281
LauncherAllAppsContainerView #7f090098 (apps_view)
含义:完整的 View 层级结构,展示了从 DecorView 到每个子 View 的树状关系。
下面图这个桌面的view展示情况就可以与上面布局完全匹配,偶尔需要自己模拟触摸事件,或者说让ai来模拟点击测试时候,如果ai不知道如何获取控件坐标也可以提醒使用这种dump方式。
关键视图与源码对应:
LauncherRootView | |
DragLayer | |
Workspace | |
CellLayout | |
QsbContainerView | |
Hotseat | |
PageIndicator | |
DropTargetBar | |
ScrimView | |
LauncherRecentsView | |
OverviewActionsView | |
LauncherAllAppsContainerView | |
PredictionRowView |
相关源码:
// QuickstepLauncher.java: setupViews()
mActionsView = findViewById(R.id.overview_actions_view);
RecentsView overviewPanel = getOverviewPanel();
overviewPanel.init(mActionsView, mSplitSelectStateController, ...);
// Launcher.java: setupViews()
mDragLayer = findViewById(R.id.drag_layer);
mWorkspace = mDragLayer.findViewById(R.id.workspace);
调试价值:这是最重要的调试区域之一:
检查 View 是否被正确添加到层级中 通过 V.E......等标志查看 View 的 visibility 和 enable 状态G.ED.....中G= GONE,I= INVISIBLE确认视图树结构是否符合预期
如何Activity等dump中加入自定义信息
这个其实Activity,Service等类本身自带了相关的dump方法:
我们只需在自己Activity方法中进行重写dump,然后加入自己的一些自定义想要dump东西
更多vip免费系统开发经典大厂面试题库获取,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥微信:


夜雨聆风