解锁、锁屏界面状态改变、锁屏(开机锁屏、时间超时锁屏、按power键锁屏)
一、解锁。以划动解锁(LockScreen.java)为例

1、划动解锁触发其控件监听方法onTrigger,onTrigger方法再调用对象mCallback.goToUnlockScreen()

2、在LockPatternKeyguardView的构造函里创建一个KeyguardScreenCallback的对象mKeyguardScreenCallback,并实现KeyguardScreenCallback的所有抽象方法。

LockPatternKeyguardView把mKeyguardScreenCallback当作LockScreen的构造函数的参数,LockScreen把该参数赋值给mCallback,所以mCallback==mKeyguardScreenCallback

3、KeyguardScreenCallback的抽象方法goToUnlockScreen的具体实现是:getCallback().keyguardDone(false)

KeyguardViewMediator当作KeyguardViewManager的构造函数的参数传给KeyguardViewManager,

然后在创建LockPatternKeyguardView对象mKeyguardView(mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this))后,

执行mKeyguardView.setCallback(mCallback);

所以getCallback().keyguardDone(false)==KeyguardViewMediator.keyguardDone(false)

4、KeyguardViewMediator.keyguardDone(false)通过传递消息ID(KEYGUARD_DONE),最终调用KeyguardViewManager.hide()方法把界面给View.setVisibility(View.GONE)方法把界面隐藏,
并清除。之后进入到launcher界面。


二、锁屏界面状态改变。以LockScreen界面的时间变化举例

LockScreen是view类型,并实现接口 KeyguardUpdateMonitor.InfoCallback的onTimeChanged()方法。

在LockScreen的构造函数里面通过执行updateMonitor.registerInfoCallback(this)把LockScreen注册到KeyguardUpdateMonitor的观察对象列表。

KeyguardUpdateMonitor注册了一个BroadcastReceiver用于监听时间、信号、电量等界面信息的变化。当时间发生变化时,BroadcastReceiver接收到Intent.ACTION_TIME_CHANGED,

之后发出消息MSG_TIME_UPDATE。Handler接收到MSG_TIME_UPDATE后执行handleTimeUpdate(),在handleTimeUpdate里面代码如下:

for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onTimeChanged();
}循环调用观察对象的onTimeChanged方法。

三、锁屏(开机锁屏、时间超时锁屏、按power键锁屏)
A、开机锁屏

当系统初始化完成后会调用wm(WindowManagerService.java).systemReady()函数,触发解锁界面。

--->PhoneWindowManager.systemReady()--->mKeyguardMediator(KeyguardViewMediator.java).onSystemReady()

-->mKeyguardMediator.doKeyguard()-->mKeyguardMediator.showLocked(){Message msg = mHandler.obtainMessage(Show) mHandler.sendMessage(msg)}

-->mKeyguardMediator.handleShow()-->mKeyguardViewManager(KeyguardViewManager.java).show()
{创建锁屏界面类mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this),之后执行mKeyguardHost.addView(mKeyguardView, lp)就可以显示界面了}

B、时间超时锁屏

当PowerManagerService.java服务建立起来后,电源的状态循环则主要是通过Handler来实现的。

PowerManagerService在初始化方法里面会启动mHandler消息循环来提供任务的延迟发送,通过mHandler.post(TimeoutTask.java,int delaytime)实现timeout机制。
注:TimeoutTask.java是PowerManagerService.java的一个内部类,用于timeout控制。

1、PowerManagerService.userActivity()里面在调用setPowerState之后会用setTimeoutLocked来设置timeout。

然后在setTimeoutLocked里面会根据当前的状态来计算下一个状态以及时间,判断完再调用mHandler.postAtTime(mTimeoutTask, when)来post一个TimeoutTask。
这样在when毫秒后就会执行TimeoutTask。

在TimeoutTask里面则根据设定的状态来调用setPowerState来改变电源状态,然后再设定新的状态,

比如现在是把屏幕从亮改暗了,那就再用setTimeoutLocked(now, SCREEN_OFF)来等下把屏幕完全关掉。如果这次已经是把屏幕关了,那这轮的timeout状态循环就算是结束了。

2、在PowerManagerService.userActivity()方法的最后面执行 mPolicy.userActivity()===PhoneWindowManager.userActivity(),其代码如下:
if (mLockScreenTimerActive) {
// reset the timer
mHandler.removeCallbacks(mScreenLockTimeout);
mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
}

mLockScreenTimeout是settings里设置的屏幕超时时间,mScreenLockTimeout是一个runable,代码如下:
Runnable mScreenLockTimeout = new Runnable() {
public void run() {
synchronized (this) {
if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
mKeyguardMediator.doKeyguardTimeout();
mLockScreenTimerActive = false;
}
}
};mKeyguardMediator.doKeyguardTimeout()是下发锁屏命令。

总的来说,就是在用户活动例如点击触摸屏之后,通过执行PowerManagerService.userActivity()重新设置系统的电源状态之后,
再通过执行mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout)设置在mLockScreenTimeout之后屏幕锁屏

C、按power键锁屏
WindowManagerService负责android系统显示的加载及事件的接收和分发。
power键是一个比较特殊的按键,power键的所有相关动作在WindowManagerService的内部类KeyQ的预处理方法preprocessEvent()截获,并且不会把事件放到KeyQ的事件列表中去
大致流程如下:
preprocessEvent()-->mPowerManager.goToSleep(event.when){PowerManagerService.goToSleep(long time)}--->PowerManagerService.goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER)

--->PowerManagerService.goToSleepLocked(long time, int reason)-->PowerManagerService.setPowerState(SCREEN_OFF, false, reason)

--->PowerManagerService.sendNotificationLocked(true, -1)--->mHandler.post(mNotificationTask)--->policy.screenTurnedOff(why)
policy即是PhoneWindowManager.java,接下去就会再去调用dokeyguard等方法进行锁屏

总的来说就是WindowManagerService截获power事件,在preprocessEvent()预处理方法里通知PowerManagerService暗下去,在PowerManagerService在屏幕暗下去的过程中调用
PhoneWindowManager去再创建锁屏界面
注:在因power键创建锁屏的过程中,PhoneWindowManager会去把mScreenLockTimeout从消息对列中去掉,以免冲突代码如下:
private void updateLockScreenTimeout() {
synchronized (mScreenLockTimeout) {
Log.d("cai","6666666666666666666-------");
boolean enable = (mAllowLockscreenWhenOn && mScreenOn && mKeyguardMediator.isSecure());
if (mLockScreenTimerActive != enable) {
if (enable) {
if (localLOGV) Log.v(TAG, "setting lockscreen timer");
mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
} else {
if (true) Log.v("cai", "clearing lockscreen timer");
mHandler.removeCallbacks(mScreenLockTimeout);//把mScreenLockTimeout从消息对列中去掉
}
mLockScreenTimerActive = enable;//设置屏幕超时的timer失效
}
}
}

对于按power键让系统锁屏的流程还没搞清楚,希望知道的同学留言告知。。

更多相关文章

  1. 【Android】原生安装和卸载应用
  2. ButterKnife 使用教程
  3. Android(安卓)View框架总结(九)KeyEvent事件分发机制
  4. 面试题及答案
  5. Android事件分发机制的探索与发现之ViewGroup篇
  6. Android(安卓)BaseRecyclerViewAdapterHelper 使用中的一些坑
  7. 关于Android(安卓)Fragment生命周期以及其他方法的调用执行顺序
  8. Android(安卓)动态创建Drawable selector
  9. Android底层字符传递给上层应用举例

随机推荐

  1. Android WebView 远程网页 加载本地资源j
  2. 将Android工程做成jar包和资源文件
  3. 详述Google的Android平板App开发准则
  4. Android(安卓)Binder机制学习笔记之一
  5. Android控制闪光灯的方法(打开与关闭)
  6. Android(安卓)Studio第四期 - 导入第三方
  7. android中setVisibility方法无效的可能原
  8. Android 内核 - 00 Android模块及Linux
  9. 一个小白的Android之路
  10. Android Sip学习(四)Android自带SipDemo详