Android层级分布

adb shell dumpsys window w 命令输出内容解读指南

adb shell dumpsys window w 实际上是 adb shell dumpsys window windows 的简写形式(wwindows 的缩写)。这个命令会输出设备上所有窗口的详细信息,是调试窗口相关问题的利器。

📌 命令输出的典型结构

执行命令后,你会看到类似这样的输出:

ini 复制代码
WINDOW MANAGER WINDOWS (dumpsys window windows)
  Window #11: com.example.app/.MainActivity (u0)
    mDisplayId=0 mSession=Session{e6589e5 12345:u0a123}
    mOwnerUid=10123 mPackage= com.example.app
    mAppToken=AppWindowToken{12345 token=Token{12345 ActivityRecord{12345 u0 com.example.app/.MainActivity t12345}}}
    mAttrs=WM.LayoutParams{(0,0)(fillxfill)m=WM.LayoutParams{...}}
    mLayer=10000 mBaseLayer=10000
    mFrame=Rect(0,0 - 1080,1920)
    mSurface=Surface(name=com.example.app/com.example.app.MainActivity)
    mDrawState=HAS_DRAWN
    mShowing=true
    mSurfaceShown=true
    mSurface=Surface(name=com.example.app/com.example.app.MainActivity)
    mVisible=true
    mCurrentFocus=Window{12345 u0 com.example.app/.MainActivity}
    mFocusedApp=AppWindowToken{12345 token=Token{12345 ActivityRecord{12345 u0 com.example.app/.MainActivity t12345}}}

🔍 逐项解读

1. 窗口标识信息

bash 复制代码
Window #11: com.example.app/.MainActivity (u0)
  • #11:窗口的序号
  • com.example.app/.MainActivity:窗口所属的应用包名和Activity类
  • (u0):用户ID(通常为0表示主用户)

2. 窗口基础信息

ini 复制代码
mDisplayId=0 mSession=Session{e6589e5 12345:u0a123}
  • mDisplayId=0:显示ID(0表示主屏幕)
  • mSession:会话ID,标识窗口所属的会话

3. 窗口属性

ini 复制代码
mAttrs=WM.LayoutParams{(0,0)(fillxfill)m=WM.LayoutParams{...}}
  • 窗口的布局参数,包括位置(0,0)、尺寸(fillxfill)等

4. 窗口层级

ini 复制代码
mLayer=10000 mBaseLayer=10000
  • mLayer:窗口的层级(值越大,越在上层)
  • mBaseLayer:窗口的基础层级

5. 窗口尺寸

ini 复制代码
mFrame=Rect(0,0 - 1080,1920)
  • 窗口的矩形区域(左上角坐标(0,0)到右下角坐标(1080,1920))

6. 窗口状态

ini 复制代码
mDrawState=HAS_DRAWN
mSurfaceShown=true
mVisible=true
  • mDrawState:窗口绘制状态
    • HAS_DRAWN:窗口已绘制(是显示状态的必要条件)
    • NOT_DRAWN:窗口未绘制
  • mSurfaceShown:表面是否可见(true表示可见)
  • mVisible:窗口是否可见(true表示可见)

7. 焦点信息(关键!)

ini 复制代码
mCurrentFocus=Window{12345 u0 com.example.app/.MainActivity}
mFocusedApp=AppWindowToken{12345 token=Token{12345 ActivityRecord{12345 u0 com.example.app/.MainActivity t12345}}}
  • mCurrentFocus:当前有焦点的窗口(可能是一个视图,不一定是Activity)
  • mFocusedApp:当前有焦点的应用(总是关联到一个ActivityRecord)

📌 重要区别:当焦点切换到没有Activity的视图(如系统UI部分)时,mCurrentFocus会显示该视图,但mFocusedApp仍显示上一个Activity。

8. 应用信息

ini 复制代码
mAppToken=AppWindowToken{12345 token=Token{12345 ActivityRecord{12345 u0 com.example.app/.MainActivity t12345}}}
  • mAppToken:应用窗口令牌,标识应用的窗口
  • t12345:任务ID,标识Activity所在的任务

💡 实用场景

1. 查找当前焦点Activity

bash 复制代码
adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'

输出示例:

ini 复制代码
mCurrentFocus=Window{12345 u0 com.example.app/.MainActivity}
mFocusedApp=AppWindowToken{12345 token=Token{12345 ActivityRecord{12345 u0 com.example.app/.MainActivity t12345}}}

这表示当前有焦点的Activity是com.example.app/.MainActivity

2. 查看窗口层级关系

bash 复制代码
adb shell dumpsys window windows | grep -E 'mLayer|mDrawState'

通过比较mLayer值,可以知道哪个窗口在最上层

3. 检查窗口是否可见

bash 复制代码
adb shell dumpsys window windows | grep -E 'mSurfaceShown|mVisible'

如果mSurfaceShown=truemVisible=true,则窗口可见

4. 检查刘海屏/显示区域

bash 复制代码
adb shell dumpsys window | grep -i cutout

输出示例:

ini 复制代码
DisplayCutout: (left=0, top=0, right=0, bottom=0) 

这表示没有刘海屏,如果显示有值,则表示有刘海屏区域

📝 总结

adb shell dumpsys window w 命令的输出包含了设备上所有窗口的详细信息,是调试窗口问题(如布局异常、焦点问题、层级问题)的关键工具。

重点看以下字段

  • mCurrentFocusmFocusedApp:判断当前焦点
  • mLayer:判断窗口层级
  • mDrawStatemSurfaceShown:判断窗口是否已绘制并可见
  • mFrame:窗口的尺寸和位置

在实际工作中,通常会配合grep命令来过滤关键信息,例如:

bash 复制代码
adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp|mLayer|mDrawState'

这样可以快速获取你关心的信息,避免被大量输出淹没。

希望这个解读对你有帮助!如果你有具体的输出内容需要解读,也可以提供出来,我可以帮你分析。

相关推荐
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android