http://www.devba.com/index.php/archives/6157.html Android闪屏问题的分析思路
闪屏问题作为Android的一类常见问题,原因复杂多样.我们在这里整理一下如何分析闪屏问题,找到具体导致闪屏问题的原因.
严格从技术来说,闪屏问题不能归为一类问题,他是因为屏幕快速变化导致用户看起来显示不正常的问题(很多测试者甚至会将花屏问题当做闪屏问题,这里不做讨论).它可能是多种完全不同的原因导致的,硬件问题,驱动问题,绘制问题,合成问题,窗口调度问题,activity问题,以及app本身的逻辑问题都有可能导致用户看起来屏幕闪屏的感觉,其中百分之九十以上闪屏的问题是由后三种问题导致的.
特殊指出的是,由于闪屏问题基本都是逻辑错误而不是异常,基本难以单纯从log中看到异常信息,因此要分析闪屏问题,可复现的问题最好,如果不能,起码要保证有清晰完整的屏幕录像(adb shell screenrecord录下来的最好),否则问题无法分析.
下面我们来讲下如何分析一个可复现的闪屏问题:
1 首先来确认下问题是否和屏幕硬件以及驱动有关
1.1 屏幕录像,是不是屏幕问题?
这个问题很好确认,将手机连接电脑,输入adb shell screenrecord /sdcard/tt.mp4,稍等片刻,开始复现问题,在问题复现完毕后,停止命令执行,去手机sdcard目录下查看视频文件.
如果视频文件中问题不存在,说明这个问题和屏幕硬件驱动或者MDP合成有关系,我们需要继续区分这到底是屏幕问题还是合成问题.
1.2 是不是合成问题?
如何区分这到底是屏幕问题还是合成问题呢?打开开发者选项,勾选禁用硬件叠加选项.
重新复现问题,如果问题依然复现,说明问题是LCD驱动或者硬件层面导致,这是需要LCD组进行check;
如果问题不再复现,说明这很大可能是一个MDP合成问题,需要平台厂商进行check.
1.3 underruan问题?
这里指出一种特别的闪屏问题,如果屏幕闪烁规则的半个屏幕的蓝色或者黑色矩形,我们有理由怀疑是发生了underrun,这种闪屏问题是可以通过log来确认的,一般来说如果在log中看到显示有关的硬件打印了underrun的log,说明此时发生了underrun.一般是由于平台某个硬件带宽不足引起的,建议将问题交给平台来处理.
2 接下来我们需要看下是不是绘制或者硬件加速问题
2.1 是不是硬件加速问题?
其实,一般来说,如果闪屏只发生在某个特定的路径下,一般基本没有可能是绘制的问题或者GPU的问题(因为绘制错误只会导致花屏,不可能导致屏幕大小级别的闪屏,如果绘制或者GPU出问题导致闪屏,一般会出现整个系统所有app不分路径的闪屏),尽管可能性很小,我们也可以测试排除一下.
关闭发生闪屏的程序的硬件加速,在app的AndroidManifest.xml文件中,加入application android:hardwareAccelerated="false" ,如果问题发生在两个app切换时,关闭两个app的硬件加速,重新编译app,拷贝替换.
复现问题,如果问题继续复现,说明这个问题和绘制没有关系;如果问题不复现,需要继续排查是GPU硬件问题还是硬件加速问题导致的闪屏.
2.2 是不是GPU问题?
一般来说,如果是GPU出现问题,会不分路径的,在除了全屏视频播放之外的所有路径下都可能出现大范围的闪屏,这种情况下log中一般搜索opengl的log,会发现在闪屏的应用打出了海量的opengl error的log,这种情况下,很有可能是发生了硬件损坏,建议交给硬件部门check.
3 继续分析问题
如果经过前面的check,我们确定不是硬件的问题,不是驱动的问题,不是绘制的问题,也不是合成的问题.那基本上这个问题就是上层的问题,为了确定到底发生了什么问题,我们需要进一步的确认.
3.1 再一次的分析录像
对于闪屏问题,adb shell screenrecord录到的视频是最有分析价值的,所以我们需要进一步分析.
分析之前请下载一款具有高级视频调节功能的播放器,逐帧播放问题发生时的录像.
因为闪屏问题,很多时候是切换的问题,那么我们也可以放慢动画速度来观察现象.打开开发者选项,将其中的窗口动画比例,过渡动画比例,以及动画影像时间伸缩效果都设置为10x,这样我们也可以清晰的看到切换的时候发生了什么问题.
此时剩下的问题一般就是activity或者窗口快速切换让用户产生了屏幕在闪的幻觉,这种问题大多都可以通过查看录像慢放明显的看到不该出现的activity(窗口)出现了,这种问题就是app本身在activity的切换逻辑上有问题,这样我们就可以从app的角度进行分析(如果慢放动画可以使得现象变慢的话,我们也可以在问题发生时,抓取SurfaceFlinger的dumpsys,以及通过ADT的Hierarchy view查看闪出来的是哪个activity).
一种比较少见的问题是,app使用了某种特殊的动画效果,让测试者或者用户感觉是闪屏问题.这个时候,在开发者选项中的绘图选项中,将三个动画相关的设置都修改为动画已关闭.如果问题消失,那么可以确定是app自身使用了某种特殊的看起来像是闪屏的动画效果.
当然还存在另外一种情况,窗口数量是正常的,但是窗口之间在不正常的频繁切换.
对于后一种情况,只靠查看视频还不能完全确认,我们还需要查看log来进一步确认.
3.2 查看log中窗口的变更和绘制
窗口之间在不正常的频繁切换,对待这种问题,一个最简单有效的办法是,在问题复现时,保持手指一指触摸屏幕,然后抓取log,我们会看到触摸的焦点窗口一直在高速变化,如下:
- 11-01 10:45:07.047: D/InputDispatcher(1106): Focus left window: Window{1784331e u0 ..}
- 11-01 10:45:07.087: D/InputDispatcher(1106): Focus entered window: Window{1784331e u0 ...}
- 11-01 10:45:07.207: D/InputDispatcher(1106): Focus left window: Window{1784331e u0 ...}
- 11-01 10:45:07.237: D/InputDispatcher(1106): Focus entered window: Window{1784331e u0..}
- 11-01 10:45:07.257: D/InputDispatcher(1106): Focus left window: Window{1784331e u0 ...}
- 11-01 10:45:07.287: D/InputDispatcher(1106): Focus entered window: Window{1784331e u0 ..}
这样我们就可以断定是app在进行不正常的window切换,我们就可以从app的角度检查一下在问题发生时activity的切换逻辑了.