Android 7.0 Keyguard流程分析

本文详细分析了Android 7.0中的Keyguard流程,从KeyguardViewMediator的启动开始,涵盖SystemUI启动、POWER键灭屏时Keyguard加载、锁屏方式的保存、解锁机制以及framework层Keyguard的保存与读取。重点讨论了解锁流程、通知界面滑动、异常栈定位以及Android M前后锁屏密码的存储差异。
摘要由CSDN通过智能技术生成

在android 6.0 上Keyguard作为了SystemUI的一个库文件被引用,所以编译的时候不会出现Keyguard.apk这个文件,Keyguard也伴随着SystemUI的启动而启动,其中最重要的一个文件就是KeyguardViewMediator,这个文件负责SystemUI与Keyguard的交互,我们来看一下这个文件的启动。


一.KeyguardViewMediator的启动

KeyguardViewMediator.java作为SystemUIApplication.java中SERVICES[]中的一个元素,我们用一个流程图来说明这个文件的启动过程,这个数组中的其它元素启动顺序与这个类似,只是功能不同而已。


从上面的流程图中可以看到KeyguardViewMediator.java的启动分为两部分。

1.SystemUIApplication.java的onstart()

SystemUIApplication.java的onstart()调用,这个调用会初始化锁屏相关的工具类,但是需要注意这个步骤中没没有初始化任何锁屏界面相关的东西,只是进行一些Intent的注册以及一些必要的初始化工作。其中KeyguardDisplayManager.java会作为中间类去控制keyguard的show与hide,KeyguardUpdateMonitor.java中注册了绝大多数的广播,负责处理界面的一些刷新流程处理,还有一个需要特别注意一下就是FingerManager.java,这个类是android 6.0 新添加的,负责处理一些指纹相关的东西。

2.SystemUIApplication的onBootCompleted()

这个函数会去发送锁屏加载完成的广播,USER_PRESENT_INTENT,但是需要注意这个函数的调用时机。这个函数的调用是received到系统发送的ACTION_BOOT_COMPLETED,根据实际工作中的经验, ACTION_BOOT_COMPLETED的发送比较偏后,在系统绝大多数的界面处理完成以后才会发送,在看到锁屏之后,也就是说,如果我们监听到 USER_PRESENT_INTENT,那么锁屏一般是肯定加载完成了的。

备注:锁屏界面的初始化是在SystemBar.java的onStart()方法中处理的,这个方法比较复杂,我们在SystemUI的分析中在细说。初始化是在onStart(),但是锁屏的加载需要经过一些特殊条件的触发与判断,由于开机第一次锁屏的加载是需要经过ActivityManagerService.java中界面的判断与WindowMnaagerService.java中界面绘制的处理才决定是否显示,牵扯的比较负责,暂时不分析,后续专门分析这部分。

二.SystemUI的启动

Keyguard是SystemUI的一个库文件,所以分析Keyguard我们需要先看一下SystemUI的启动。流程图简单分析如下:

PhoneStatusBar.java中的createAndAddWindows()会初始化并且加载SystemUI的绝大多数界面,包括statusbar与navigationbar,以及初始化QSHostView。这部分代码需要仔细阅读代码,注意细节,用到这些细节的时候我们再仔细分析。

至此,keyguard以及systemUI启动初始化加载完毕,SystemService.java中的startSystemUI()函数执行完毕。

三.POWER键灭屏时Keyguard的加载

我们知道用power键灭屏的时候会加载keyguard,这样可以保证亮屏的时候终端用户可以第一时间看到锁屏,保证良好的用户体验,我们用这个场景来分析锁屏的加载过程。

1.PowerManagerService亮屏流程


上述流程图从power按键的分发到PowerManagerService.java的处理,再到keyguard相关的代码处理,这条线路传到KeyguardViewMediator.java中以后就要开始锁屏界面的绘制了。稍后专门对锁屏界面的绘制进行说明。

备注:
亮屏过程中涉及到两条关键的线程,分别是PowerManager Notifier Thread 与DisplayManager Thread。
1.PowerManager Notifier Thread:power按键事件传到PowerManagerService.java中以后会分为两条线路进行事件处理,一条就是我们上面流程图上标注的,这条Thread(Notifier.java)主要负责亮屏或者灭屏广播的发送,以及锁屏界面的加载。
2.DisplayManager Thread:这条Thread会 传送到DisplayManagerService.java中去,会负责进行屏幕状态的设置以及屏幕的熄灭与点亮(真正的屏幕操作者),此外跟屏幕相关的一些可见性操作都是这条Thread(DisplayPowerController.java)进行处理,例如屏幕亮度的变化、屏幕亮度的设置、屏幕的显示时机等等,非常重要,有时间可以研究研究。

2.KeyguardManager.java的说明

APP侧开发锁屏应用,调用的接口是KeyguardManager.java或者内部类KeyguardManager.KeyguardLock,用这个manager来获取或者设置锁屏的一些状态,这样就可以控制锁屏的显示。需要添加对于的权限到AndroidMainfest.xml文件中, android.permission.DISABLE_KEYGUARD。
对这个类的详细介绍以及用法介绍请参考如下网址: http://blog.csdn.net/hudashi/article/details/7073373
我们简单的来分析一下这个调用过程,也用流程图来说明一下

从这个流程图不难发现,不管APP侧怎么调用KeyguardManager.java的接口,最终的实现都是在KeyguardViewMediator.java中。KeyguardService.java是Binder的服务器端,客户端是KeyguardServiceDelegate.java, KeyguardServiceDelegate.java 这个文件在调用过程中只起到过渡的左右,在这里并没有深入研究。 KeyguardService.java会将所有的调用传递到 KeyguardViewMediator.java中。
备注:
Android 6.0 的Keyguard是在SystemUI中控制的,SystemUI是一个系统级的APK,要操作锁屏还是需要使用上述这些东西。所以如果需要改变锁屏的一些流程,我们可以在合适的位置调用KeyguardManager.java中接口,或者添加一些客制化的东西,直接在KeyguardViewMediator.java中进行操作,都是可以实现的。

3.锁屏的加载绘制过程

KeyguardViewMediator.java的onFinishedGoingToSleep()是加载锁屏的入口,接下来对这个过程进行分析。
这个过程是开机以后正常使用过程中,用power键灭屏的时候加载锁屏的流程,并且存在锁屏方式。还有其它方式的灭屏跟这个略有区别,例如亮屏超时的熄屏,但是大同小异,根本是一样的,有时间再仔细分析。


这样经过上述的流程以后,keyguard就在锁屏界面显示了,需要注意的是Android 6.0 上看到的锁屏实际上是一层通知panelview,也就是流程图上的17,如果去掉这个函数,那么界面上是不会出现通知界面的,但是锁屏也是不能用的,因为在这个函数执行之前已经通知了系统要加载锁屏,所以结果就是看上去去掉了notificationpanelview,但是实际上系统中的状态还是存在这个界面的,所以如果要从keyguard中用代码去掉这个界面,还需要其它的一些修改,需要保持界面状态的一致。

需要注意这个过程中的26:updateState(),这个函数会去更新keyguard以及systemUI的一些标志状态,保持系统状态的统一性,27会去设置更新后的这些状态值。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值