亮灭屏问题一直是Android模块最常见的问题之一。

由于问题出现问题的地方涉及到公司代码,我这里仅仅只作原生代码模块的分析

其实在看过另外一篇关于android亮屏流程的文章就会发现,影响亮屏快慢的因素大致有三种:1.设置背光流程出问题了,导致屏幕黑屏,2.window绘制时间过长,导致屏幕block时间过长;3.底层surfacecontroller准备时间过长。

而根据遇到的亮屏慢的问题,基本上都是由于window绘制时间过长,导致屏幕亮屏慢

最近处理的几个亮屏慢的问题,其中关键log信息基本都是:

10-28 09:02:59.002  1393  1462 I DisplayPowerController: Blocking screen on until initial contents have been drawn.

10-28 09:03:05.020  1393  1462 I DisplayPowerController: Unblocked screen on after 6018 ms

由于在android亮屏流程中大致描述的亮屏所走的流程点,但是仅仅只能作为一个粗略的点做参考,但是看到上面的两条信息,我们可以去追溯一下代码流程:

在每一次屏幕电源状态发生改变的都会调用的到DisplayPowerController中的updatePowerState方法,在该方法中如果屏幕状态发生改变的话,会去调用到animateScreenStateChange,在setScreenState方法里面去设置屏幕状态。那么就到了该问题的主要流程了。

在DisplayPowerController.java中的setScreenState()方法中,有代码:

[java] view plain copy
  1. if (mPowerState.getColorFadeLevel() == 0.0f) {
  2. blockScreenOn();
  3. } else {
  4. unblockScreenOn();
  5. }
  6. mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
  7. }
  8. // Return true if the screen isn't blocked.
  9. return mPendingScreenOnUnblocker == null;

首先会调用到 blockScreenOn方法,先看看该方法以及后面要调用到的unblockScreenOn的方法

[java] view plain copy
  1. private void blockScreenOn() {
  2. if (mPendingScreenOnUnblocker == null) {
  3. Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
  4. mPendingScreenOnUnblocker = new ScreenOnUnblocker();
  5. mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
  6. Slog.i(TAG, "Blocking screen on until initial contents have been drawn.");
  7. }
  8. }
  9. private void unblockScreenOn() {
  10. if (mPendingScreenOnUnblocke != null) {
  11. mPendingScreenOnUnblocker = null;
  12. long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime;
  13. Slog.i(TAG, "Unblocked screen on after " + delay + " ms");
  14. Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_TRACE_NAME, 0);
  15. }
  16. }

在blockScreenOn函数中其实就是创建了一个mPendingScreenOnUnblocker 对象,当该对象为空时,mPendingScreenOnUnblocker == null;返回值才为true。animateScreenStateChange才能继续往下执行下去。

亮屏过程中绘制window过程是通过mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); 调用到PhoneWindowManager中的screenTurningOn(),

[java] view plain copy
  1. private final class ScreenOnUnblocker implements WindowManagerPolicy.ScreenOnListener {
  2. @Override
  3. public void onScreenOn() {
  4. Message msg = mHandler.obtainMessage(MSG_SCREEN_ON_UNBLOCKED, this);
  5. msg.setAsynchronous(true);
  6. mHandler.sendMessage(msg);
  7. }
  8. }

可以看到mPendingScreenOnUnblocker是继承了WindowManagerPolicy.ScreenOnListener这个接口,而该接口同样是作为一个callback到PhoneWindowManager那边去绘制window,当all window for drawn 完成之后,会回调到 mPendingScreenOnUnblocker的onScreenOn,会去unblock屏幕

这里用一个图来详细描述

可以看到 整个过程调用的点较为混乱,这里只能简单描述一下其调用过程当PowerManagerService发出的wakeup请求到DisplayPowerController这边,在DisplayPowerConrtoller中setScreenState方法中会调用到PhoneWindowManager模块的screenTurningOn方法去通过window绘制屏幕。

由于在灭屏之后亮屏首先现实的界面应该是锁屏界面,所以亮屏首先应该去绘制keyguard,并且keyguard经常会出现超时,当出现keyguard超时时会打印:

WindowManager:Keyguard drawn timeout. Setting mKeyguardDrawComplete

当出现上述打印,便可以确定时keyguard模块绘制锁屏超时,需要锁屏的人去确认超时原因。锁屏超时时间最长也只有2秒时间。因为

[java] view plain copy
  1. if (mKeyguardDelegate != null) {
  2. mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
  3. mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
  4. mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
  5. } else {

当mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);正常执行完成的情况下会调用到finishKeyguardDrawn,当未能正常执行,超过1秒还未完成便会发送消息MSG_KEYGUARD_DRAWN_TIMEOUT强制执行finishKeyguardDrawn,

在finishKeyguardDrawn完成后会检查所有的亮屏后所依赖的window是否都绘制完成,在mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,WAITING_FOR_DRAWN_TIMEOUT);//WAITING_FOR_DRAWN_TIMEOUT = 1000 中会去检查window绘制,如上,当超过1秒后,会自动release等待的window,然后正常亮屏。

原文地址:http://blog.csdn.net/u011311586/article/details/53174280

(原创)Android6.0亮屏流程之Keyguard Window绘制相关推荐

  1. (原创)Android6.0亮屏流程分析

    1.概述 Android的亮屏流程从android系统结构层次来分可以分为三个流程,App应用唤醒源:Framework层Power结合Display,Light服务做亮屏绘制准备工作:底层驱动点亮背 ...

  2. Android6.0 亮屏灭屏流程(DisplayPowerControler、WMS)(二)亮度设置

    http://blog.csdn.net/kc58236582/article/details/54616756 上一篇博客我们主要分析了在setScreenState中调用PhoneWindowMa ...

  3. 三星android6.0推送,三星推送Android6.0 满屏小清新的风味!

    原标题:三星推送Android6.0 满屏小清新的风味! 最新消息,三星已经开始陆续为韩版S6\S6 Edge用户推送Android6.0"棉花糖"更新,可能再过一段时间会陆续扩展 ...

  4. android 7.0 解锁亮屏,Android7.0亮屏流程分析

    亮屏的本质是改变屏幕的电源状态,经过一系列的调用会来到PowerManagerService中的updatePowerStateLocked() 1.PowerManagerService到Displ ...

  5. 源码详解Android 9.0(P) 系统启动流程之SystemServer

    源码详解Android 9.0(P) 系统启动流程目录: 源码详解Android 9.0(P)系统启动流程之init进程(第一阶段) 源码详解Android 9.0(P)系统启动流程之init进程(第 ...

  6. android6.0分屏插件,xposed分屏模块安卓6.0下载

    安卓6.0系统分屏软件(xposed分屏插件)是一款支持分屏多任务软件,具有多窗口/双窗口功能,在众多智能分屏app中算是比较好用的啦,推荐给有需要的用户下载使用! 安卓6.0多窗口分屏软件简介 XH ...

  7. 魅族 android6.0,大屏又好用的 MEIZU 魅蓝MAX及Flyme6.0初体验

    大屏又好用的 MEIZU 魅蓝MAX及Flyme6.0初体验 2017-01-03 15:49:10 9点赞 11收藏 28评论 其实这个手机已经买了快2个月了,奈何拖延症犯了.....一直不想写,拖 ...

  8. android6.0花屏6,微信6.5安卓内测版Bug,部分机型花屏成这样了

    原标题:微信6.5安卓内测版Bug,部分机型花屏成这样了 微信安卓版6.5内测版在前几天推动报名了,但无奈安卓手机的机型和版本太多,部分机型出现了小视频录制的BUG.这里简单介绍下! . 本次更新的最 ...

  9. 单击屏幕亮屏流程分析

    一. kernel部分 1.看TP驱动有没有事件上报  cat /dev/input/evnet1  或者看kernel log [ 4036.282237] bt541_ts_device 5-00 ...

最新文章

  1. 微服务如何设计一个配置中心
  2. Windows服务程序时钟调用
  3. ner 评估指标_序列标注算法评估模块 seqeval 的使用
  4. 罗永浩直播带货被吐槽不是全网最低价 本人亲自回应了
  5. mysql 安装、建库、导入导出数据
  6. Centos 5.2安装Cacti并集成Nagios安装文档
  7. 【Python K均值聚类算法】
  8. 微信小程序性能优化实用建议
  9. html太极旋转css,前端CSS技巧之太极旋转图详解
  10. H5:使用video标签在页面中插入视频
  11. MathWorks官方MATLAB/Simulink基础入门视频教程 笔记(matlab基础)
  12. opencv cv2.THRESH_OTSU 二值化
  13. gps纠偏及大陆地图偏移原因
  14. Linux中Kill进程的N种方法
  15. 五种常见的计算机高级语言,[转]计算机语言的种类总结
  16. 炸金花游戏(2)--炸金花游戏的胜率预估
  17. 人工智能技术发展历史
  18. python读excel并写入_python——向Excel读取或写入数据
  19. 2345看图王2345Pic10.4.0.9254_x64官方净化版
  20. 定制Android版本的chromium之笔记

热门文章

  1. iOS --高仿QQ空间页面
  2. MessageDigest简单介绍
  3. Python学习笔记:虚拟环境和包
  4. 救援模式下更改用户密码
  5. Linux下必须知道的11个网络命令
  6. Linux服务器安装NodeJs简易方法
  7. caffe中solver.prototxt文件参数解释
  8. 【算法】一个简单的决策树(DT)原理
  9. 从二分类到多分类的迁移策略
  10. 吴恩达的 CS229,有人把它浓缩成 6 张中文速查表!