Android 常见dumpsys方法与黑屏问题分析处理总结

马肤
这是懒羊羊

黑屏问题介绍

黑屏问题是显示相关的综合性问题,涉及Android应用层、框架层和底层SurfaceFlinger、屏显等多个领域。下面有一些基础的判断来定位黑屏问题的归属:

(1) 屏幕没有亮屏、背光为0则需先从power、屏显角度分析

(2) 屏幕黑屏,但可以进行三指截屏、power键+音量下键截屏,并且截图正常显示(非黑图),则需先从屏显角度分析

(3) 视频类、相机类显示黑屏,需要先确认编解码、阅览显示问题

(4) 应用界面局部性黑块,某个控件黑,确认应用的view问题

常见分析手段

从显示系统入手,软件架构从上到下分层,黑屏问题主要分为应用领域、窗口领域、SF&屏显&底软领域黑屏;分析黑屏问题,首先确认黑屏的是哪个界面(layer),然后才确认造成该界面黑的原因;而分析手段主要是通过dump数据、Activity生命周期、systrace、截图的raw数据、窗口绘制状态、视频操作等。

SurfaceFlinger

adb shell dumpsys SurfaceFlinger > SurfaceFlinger .txt

确认当前的dump SurfaceFlinger 数据对应黑屏现象的时间点

首先,确认HWC layers合成显示的图层是否为对应黑屏时应该显示的应用图层;接着,核查是否存在焦点图层【focused】(有星号的表示有焦点图层),该图层是否对应所需的显示图层;然后,核对位置【Disp Frame (LTRB)】、大小【Source Crop (LTRB)】、旋转角度【 Frame Rate 】是否正常。

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第1张

如果启动某个应用黑屏,而当前SurfaceFlinger .txt的layer不存在该应用的layer,那需要进一步确认显示buffer的数据是否正常。

从上面的SurfaceFlinger .txt dump 数据可以看出,BufferStateLayer表示当前绘图窗口,ContainerLayer是其父容器,不会有绘图buffer,父子是从上到下层次树形成;BufferStateLayer的绘图buffer是activeBuffer,该处可以看出已经完成绘图,而未完成绘图状态:activeBuffer=[ 0x 0: 0,Unknown/None]。

+ BufferStateLayer (com.example.mysystemdialog/com.example.mysystemdialog.MainActivity#117) uid=10117
  Region TransparentRegion (this=0 count=0)
  Region VisibleRegion (this=0 count=1)
    [  0,   0, 1440, 2960]
  Region SurfaceDamageRegion (this=0 count=0)
      layerStack=   0, z=        0, pos=(0,0), size=(1440,2960), crop=[  0,   0,   0,   0], cornerRadius=0.000000, isProtected=0, isTrustedOverlay=0, isOpaque=0, invalidate=0, dataspace=Default, defaultPixelFormat=RGBA_8888, backgroundBlurRadius=0, color=(0.000,0.000,0.000,1.000), flags=0x00000100, tr=[0.00, 0.00][0.00, 0.00]
      parent=9f63fd7 com.example.mysystemdialog/com.example.mysystemdialog.MainActivity#116
      zOrderRelativeOf=none
      activeBuffer=[0x0:0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0 metadata={dequeueTime:97987454113, windowType:1, ownerPID:2202, ownerUID:10117}, cornerRadiusCrop=[0.00, 0.00, 0.00, 0.00],  shadowRadius=0.000, 

另外我们还需要重点关注两个参数:color和flags,color的最后一个参数表示alpha,如果该参数为0,该图层也是不会显示的;flag参数在2进制状态的末位bit表示可见性,1表示不可见,0表示可见。也可以总结为flag是偶数表示图层可见,是奇数表示图层不可见。

(如果能获取当前界面的截图,并且是raw格式图片,则可以通过使用irfanview查看对应的图片内容 https://www.irfanview.com/)

window -a

adb shell dumpsys window -a > window .txt

前面dump sf.txt没有对应的layer显示,那么可以查看dump window的数据,确认对应应用的窗口显示状态。搜索Window #,找到对应的Window。

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第2张

这里对应的Window为我自己的 应用界面,上面信息描述了该窗口的基本信息,重点需要关注mDrawState=HAS_DRAWN,mDrawState为窗口的绘制状态,HAS_DRAWN表示WMS已经完成该窗口的显示流程。其中,NO_SURFACE、DRAW_PENDING这两个状态表示应用端没有完成对应的surface申请和绘制,此类问题需要应用端查看;COMMIT_DRAW_PENDING、READY_TO_SHOW,表示应用端已经完成绘制并上报状态给WMS,则需要WMS查看显示控制流程。

isOnScreen=true、isVisible=true这两个变量也很重要,确认当前窗口已经是可见,并显示到屏幕上;其他的,如请求宽高、frame大小、位置也可以一一确认。

窗口流程见: WMS窗口相关流程

activity activities

adb shell dumpsys activity activities > activities.txt

dumpsys activity activities可以确认当前启动的activity显示状态。该数据,从top遍历到bottom,从Task到里面的activity,把activity的信息,包含属于哪个应用、由谁启动、通过哪个Intent等。其中,确认该acitivity的窗口是否正常绘制,主要看信息mNumInterestingWindows=1 mNumDrawnWindows=1 allDrawn=true。

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第3张Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第4张

mNumInterestingWindows表示需要绘图的窗口数目,mNumDrawnWindows表示已经完成绘图的窗口数目。这里都为1表示已经完成绘图。这里里面可以看到很多信息,例如:

Keyguard的显示状态

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第5张InsetsState状态

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第6张Display areas z order

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第7张

activity top

adb shell dumpsys activity top > top_activity.txt

当启动应用黑屏,使用raw工具可以确认应用绘制送帧为黑色,也可以找到有问题的acitivity对比dump activity top的View Hierarchy:层级树,对比正常的是否加载。

Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第8张

activity 生命周期,event.log

通过 event.log分析activity生命周期情况,确认应用的activity是否执行了onResume,focus是否切换到焦点窗口,甚至应用存在anr等情况。

使用winscope

手机要处于root状态才能使用

  • 使用手机自带的winscope

    在手机设置里面,找到开发者选项->快捷设置开发者图块->打开 “ Winscope跟踪 ”

    打开后复现问题,最后再关闭这个开关,就表示抓取完成

    导出文件adb pull /data/misc/wmtrace

    把导出文件在源码路径的android-13.0.0_r6/prebuilts/misc/common/winscope/winscope.html打开即可

  • 使用脚本抓取winscope(推荐)

    附链接:winscope-t

    下载后,连接手机,直接运行脚本中的./run.sh

    Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第9张 START TRACE: 可以持续dump window和SurfaceFlinger信息,一般适用于闪黑场景,复现之前按下,复现后停止即可。

    DMUP STATE: 相当于就是抓取一次 dumpsys window和dumpsys SurfaceFlinger

    其他方法

    android trace和backtrace文件的抓取与查看方法

    分析步骤

    分析方法有很多根据个人习惯分析即可

    确认问题现象

    通过录屏来观察黑屏的过程,确认问题时间点

    如果在录像过程中,有对黑屏现象截图,发现截图正常,但是屏幕是黑的,可以直接判断为屏显问题

    dump关键log

    adb shell dumpsys SurfaceFlinger > ./dump/SurfaceFlinger.txt
    adb shell dumpsys window -a > ./dump/window.txt
    adb shell dumpsys activity activities > ./dump/activities.txt
    adb shell dumpsys activity top > ./dump/top_activity.txt
    adb shell dumpsys activity containers > ./dump/containers.txt
    adb shell dumpsys input > ./dump/input.txt
    

    找到问题窗口

    可以通过dump的SurfaceFlinger 、window 找到问题窗口

    分析dump信息

    同样不分先后顺序,按个人习惯即可。

    1、SurfaceFlinger

    ①看SurfaceFlinger中是否有对应的图层,即是否合成显示,如果没有可以先看dump的window,见第2步

    ②有图层则通过id找到对应的Layer和BufferStateLayer

    Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第10张Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第11张我们可以看到Layer 后有一串16进制数,同这个可以在log文件里面找到对应raw文件,使用irfanview工具,看其图层内容,如果本身就是黑屏,大概率是应用问题,见第2步、第3步可以进一步确认

    Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第12张

    Display表示哪块屏幕active,我们看activie的hwc layers,带SurfaceView的图层表示应用显示的内容,常见的视频、游戏等应用都有这个图层,该图层的是否显示主要是看其BufferStateLayer中的activeBuffer、flag

    activeBuffer=[ 0x 0: 0,Unknown/None]表示未完成绘图状态

    flag为偶数表示图层可见,是奇数表示图层不可见,例如:flags=0x00000100表示可见

    2、window

    找到有问题的窗口查看关键的参数

    mDrawState确认窗口绘制状态

    isOnScreen、isVisible当前窗口已经是可见,并显示到屏幕上

    NO_SURFACE、DRAW_PENDING这两个状态表示应用端没有完成对应的surface申请和绘制,此类问题需要应用端查看;COMMIT_DRAW_PENDING、READY_TO_SHOW,表示应用端已经完成绘制并上报状态给WMS,则需要WMS查看显示控制流程。

    窗口显示相关方法工作内容解释
    addWindowApp向WMS请求添加窗口记录,会在WMS里新建WindowState(NO_SURFACE)
    relayoutWindowApp向WMS申请surface用于绘制,执行后window拥有了surface(NO_SURFACE->DRAW_PENDING)
    finishDrawingWindowApp在surface上完成绘制后,通知WMS(DRAW_PENDING->COMMIT_DRAW_PENDING)
    commitFinishDrawingLockedWMS遍历window,对于完成绘制的window(COMMIT_DRAW_PENDING->READY_TO_SHOW)
    performShowLocked判断系统是否允许窗口显示isReadyForDisplay(READY_TO_SHOW->HAS_DRAWN)
    showSurfaceRobustlyLocked对HAS_DRAWN状态的窗口,用SurfaceControl通知SurfaceFlinger显示出来

    如果dump上没有显示绘制状态则可以在日志中搜索:*windowmanager.mDrawState

    3、activity top

    对比正常的dump,查看View Hierarchy:层级树是否存在异常

    4、生命周期

    在event.log中搜索wm_和input_focus查看应用生命周期是否已经走到了onresume,窗口焦点是否正常(Focus entering到了焦点)

    5、其他异常log

    例如常见的ANR,OOM等

    案例

    抖音黑屏

    1.视频播放输入输出数据正常

    2.dump SurfaceFlinger 中没有抖音图层

    3.dump SurfaceFlinger 中mDrawState为NO_SURFACE

    4.应用生命周期有走到onresume流程,当前焦点窗口为空,与前面NO_SURFACE对的上

    5.在日志中查看是否有异常log,发现有OOM(OutOfMemoryError)

    查找dump命令的方法

    代码路径:frameworks/base/core/java/android/content/Context.java

    这个代码里面有很多serviceName,比如输入法:

    Android 常见dumpsys方法与黑屏问题分析处理总结,在这里插入图片描述,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,服务,操作,没有,第13张我们可以看到,其实就是通过getSystemService方法中调用的字符常量,我们要dump输入法服务相关的命令就是adb shell dumpsys input_method

    如果我们想知道这个dump的方法具体在哪,会有哪些打印,则只需通过对应Mananger找到对应的ManagerService即可。

    比如,我们这里以输入法为例,那么其对应的就是InputMethodManagerService,在这个里面就有对应的dump方法:

    代码路径:frameworks/base/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java

    void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
                final SimpleDateFormat dataFormat =
                        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);
                for (int i = 0; i 
                    
                    
                    

文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复:表情:
评论列表 (暂无评论,0人围观)

还没有评论,来说两句吧...

目录[+]

取消
微信二维码
微信二维码
支付宝二维码