读书人

学习android内核 - android 4.0 系统锁

发布时间: 2013-09-08 15:21:21 作者: rapoo

学习android内核 -- android 4.0 系统锁屏

本文主要是记录一些在学习过程中关键路径的笔记,方便以后回忆。所以个人写得部分会很少,大部分都是摘自于它人,主要是做了一些汇总整理。

以后有机会会慢慢自己写一些。

参考:《



锁屏模块位于framework中,有别于一般的上层应用,它的逻辑代码和view视图,资源文件散布在framework的几处地方,这也给新手分析该模块带来也一点的麻烦。下面我会试着来捋捋这些散落的珠子。

1.文件目录:

a,逻辑是Frameworks/base/policy/src/com/android/internal/policy/ impl/目录下

学习android内核 - android 4.0 系统锁屏

b,视图view是在 Framework/base/core/java/com/android/internal/ widget/路径下:

学习android内核 - android 4.0 系统锁屏

文件夹multiwaveview就是从4.0开始加入的环形解锁视图及相应动画实现。

c,资源文件在Framework/base/core/res/res/下。

这个就不贴目录了,和一般android应用一样,图片资源,布局文件都很规矩的放在相应分辨率的文件夹下。大致了解了锁屏模块文件分布后,我们一般就要开始看源代码了。


2,keyguard锁屏流程图:

学习android内核 - android 4.0 系统锁屏


接着我们来看看LockScreen的时序图:

学习android内核 - android 4.0 系统锁屏

PhoneWindowManager:开机启动时会有执行到PhoneWindowManager.systemReady()[之前还有很多执行过程,这里是指执行到这里时],调用KeyguardViewMediator.onSystemReady()进行待机锁屏及解锁逻辑。(在本类(继承自WindowManagerPolicy)进行了KeyguardViewMediator的实例化,并运行在该线程上。锁屏的UI界面也是在这个线程上创建及显示的)。还有一些对电源监听处理,来执行相应的锁屏处理(手机黑屏,锁屏界面会马上出来,防止下次亮屏时会闪烁)。


----------------

KeyguardViewMediator:是整个待机解/锁屏业务的调度器,负责调度锁屏界面的相关动作及查询解锁屏状态。

KeyguardViewMediator类提供的状态查询api可以被诸如android.view.WindowManager、com.android.server.InputManager等其它线程调用,所以,KeyguardViewMediator类上的这些api方法都是线程同步的(synchronized)。

KeyguardViewMediator可以进行的调度操作包括:
1) 点亮屏幕pokeWakelock();
2) 报告锁屏权限验证是否成功keyguardDone(boolean);
3) 响应SIM卡状态变化并对锁屏界面做相应的调整onSimStateChanged()。
4) 调度待机锁屏UI界面的管理;包括显示handleShow ()、隐藏handleHide ()、重置handleReset ()、点亮屏幕handleWakeWhenReady()等,KeyguardViewMediator实现这部分调度是通过持有一个KeyguardViewManager来实现的。
---------------------------

KeyguardUpdateMonitor:是所有会影响整个待机解/锁屏业务的事件的监控器。(监控诸如时间改变、电池状态改变、时区改变、SIM卡状态变化、电话状态变化、电话信号变化等事件)

它是一个观察者模式的被观察对象。观察者通过调用KeyguardUpdateMonitor的registerInfoCallback(InfoCallback)和registerSimStateCallback(SimStateCallback)方法进行注册,观察自己感兴趣的变化。KeyguardUpdateMonitor的观察者包括KeyguardViewMediator、LockScreen、PatternUnlockScreen、AccountUnlockScreen、PasswordUnlockScreen、SimUnlockScreen等。观察者通过调用KeyguardUpdateMonitor的removeCallback(Object)取消观察。

-------------------------

KeyguardViewManager负责管理待机屏UI界面的创建、显示、隐藏、重置以及通过一个回调KeyguardViewCallback通知调度器KeyguardViewMediator进行相关的调度

------------------

LockPatternKeyguardView(KeyguardViewBase)是所有锁屏和解锁UI界面的宿主

它有2个模式Mode. LockScreen和Mode. UnlockScreen。它负责根据当前上下文环境切换当前应该显示的待机屏。它提供一个回调给当前显示的待机屏并处理其回调,如果回调动作是自己处理不了的,则继续报告给KeyguardViewMediator进行处理。
 锁屏界面就是LockScreen;解锁界面包括SIM卡解锁SimUnlockScreen、图案解锁PatternUnlockScreen、密码解锁PasswordUnlockScreen、帐号解锁AccountUnlockScreen

-----------------------

解锁成功后,锁屏流程转到KeyguardViewMediator的keyguardDone(boolean, boolean) 进行后续的流程(如转到Launcher桌面)。



3,keyguard锁屏view层次图:

学习android内核 - android 4.0 系统锁屏

学习android内核 - android 4.0 系统锁屏

一般4.0真机都会有五种锁屏方式:

学习android内核 - android 4.0 系统锁屏

这里和2.3有明显区别了,2.3的view视图如下:


可以看出来以前的锁屏流程是分正常锁屏和图案锁屏方式。在选择图案解锁方式,是不会显示正常解锁slidingview的。但是选择密码解锁就会出现需要用户二次解锁的情况。三星2.2就对此进行了流程优化统一。本人也试着做了,有兴趣可以。。。

4.0以后该流程得到了官方的统一,选择任何锁屏方式,用户都只需要一次解锁。流程上也更直观了。相信Google,必须是越来越good。


另2.2:

学习android内核 - android 4.0 系统锁屏



关键汇总:

1.LockPatternKeyguardView[作为LockScreen和UnLockScreen界面的载体,控制显示哪个界面]继承自KeyguardViewBase[为LockPatternKeyguardView提供了一组通用的方法](KeyguardViewProperties创建一个KeyguardViewBase实例)
2.LockPatternKeyguardViewProperties创建一个LockPatternKeyguardView对象
3.LockScreen extends KeyguardScreen
4.KeyguardScreenCallback[每个需要显示的界面:LockScreen或者UnLockScreen都保存了该对象的唯一实例,用来向控制界面汇报情况] extends KeyguardViewCallback[提供了一些接口用来接受用户操作Screen的结果]
5.KeyguardViewManager [包装了WindowManager功能了,提供了添加、删除锁屏界面的功能]implements KeyguardWindowController[提供通用 接口,判断该界面是否需要显示输入法窗口]
6.PhoneWindowManager -> KeyguardViewMediator -> KeyguardViewManager -> LockPatternKeyguardViewProperties -> LockPatternKeyguardView

KeyguardUpdateMonitor该类的主要功能就是根据监视系统状态值的改变(例如:时间、SIM卡状态、电池电量;使用广播监听),根据这种状态值的改变回调监听了该状态信息的对象实例




相当类及其方法作用介绍:


1、 KeyguardScreen 类 接口


功能:该接口的主要功能是为每个需要显示的界面:LockScreen或者UnLockScreen定义了四个方法,使其在不同的状态能够

得到相应处理。优点就是: 利用设计原则的面向接口编程,减少对具体对象的依赖。

路径:\frameworks\base\policy\src\com\android\internal\policy\impl\KeyguardScreen.java

其源代码释义如下:

[java] view plaincopyprint?
  1. /**
  2. * Common interface of each {@link android.view.View} that is a screen of
  3. * {@link LockPatternKeyguardView}.
  4. */
  5. public interface KeyguardScreen {
  6. /** Return true if your view needs input, so should allow the soft
  7. * keyboard to be displayed. */
  8. boolean needsInput(); //View是否需要输入数值,即该界面需要键盘输入数值
  9. /** This screen is no longer in front of the user.*/
  10. void onPause();//当该界面不处于前台界面时调用,包括处于GONE或者该界面即将被remove掉
  11. /** This screen is going to be in front of the user. */
  12. void onResume();//相对于onPause()方法,当该界面不处于前台界面时调用,处于VISIBLE状态时调用
  13. /** This view is going away; a hook to do cleanup. */
  14. void cleanUp();//该界面即将被remove掉 ,即不在需要
  15. }


2、KeyguardScreenCallback类 接口


功能:每个需要显示的界面:LockScreen或者UnLockScreen都保存了该对象的唯一实例,用来向控制界面汇报情况。

路径:frameworks\base\policy\src\com\android\internal\policy\impl\KeyguardScreenCallback.java

其源代码释义如下:

[java] view plaincopyprint?
  1. /** Within a keyguard, there may be several screens that need a callback
  2. * to the host keyguard view.
  3. */
  4. public interface KeyguardScreenCallback extends KeyguardViewCallback {
  5. /** Transition to the lock screen*/
  6. void goToLockScreen(); //当前界面跳转为LockScreen ,而不是UnLockScreen
  7. /** Transition to the unlock screen.*/
  8. void goToUnlockScreen();//LockScreen成功开锁 ,是否需要显示UnLockScreen,否则,直接开锁成功。
  9. //忘记了开锁图案,即我们需要跳转到Google 账户去开锁。
  10. void forgotPattern(boolean isForgotten);
  11. boolean isSecure();//当前机器是否安全,例如:设置了图案、密码开锁等
  12. //该函数还不太懂,可能是是否只需要验证UnlockScreen界面,即可成功开锁。
  13. boolean isVerifyUnlockOnly();
  14. /**Stay on me, but recreate me (so I can use a different layout).*/
  15. void recreateMe(Configuration config); //重新根据手机当前状态,显示对应的Screen.
  16. /** Take action to send an emergency call. */
  17. void takeEmergencyCallAction(); //紧急呼叫时的处理行为.
  18. /** Report that the user had a failed attempt to unlock with password or pattern.*/
  19. void reportFailedUnlockAttempt(); //在UnLockScreen界面登陆失败时处理
  20. /** Report that the user successfully entered their password or pattern.*/
  21. void reportSuccessfulUnlockAttempt();//在UnLockScreen界面登陆成功时处理
  22. /** Report whether we there's another way to unlock the device.
  23. * @return true */
  24. boolean doesFallbackUnlockScreenExist();
  25. }

其唯一实现类位于LockPatternKeyguardView类的内部类(稍后讲到)。


3、KeyguardViewCallback类 接口


功能: 提供了一些接口用来接受用户操作Screen的结果。

路径:frameworks\base\policy\src\com\android\internal\policy\impl\KeyguardViewCallback.java

其源代码释义如下:

[java] view plaincopyprint?
  1. /**
  2. * The callback used by the keyguard view to tell the {@link KeyguardViewMediator}
  3. * various things.
  4. */
  5. public interface KeyguardViewCallback {
  6. /** Request the wakelock to be poked for the default amount of time. */
  7. void pokeWakelock(); //保存屏幕在一定时间内处于亮屏状况 , 默认时间为5s或者10s
  8. /** Request the wakelock to be poked for a specific amount of time. */
  9. void pokeWakelock(int millis);//根据给定时间值,使屏幕在该事件段内保持亮屏状况
  10. /** Report that the keyguard is done.
  11. * @param authenticated Whether the user securely got past the keyguard.
  12. * the only reason for this to be false is if the keyguard was instructed
  13. * to appear temporarily to verify the user is supposed to get past the
  14. * keyguard, and the user fails to do so. */
  15. //成功的完成开锁,可以进入手机界面了。参数为ture表示是否正大光明的开锁,例如:图案正确,密码输入正确。
  16. void keyguardDone(boolean authenticated);
  17. /**Report that the keyguard is done drawing. */
  18. void keyguardDoneDrawing(); //整个锁屏界面draw()过程绘制完成时,回调该方法.
  19. }


其唯一实现类是 KeyguardViewMediator类(稍后讲到)


4、 KeyguardWindowController类 接口


功能:提供通用 接口,判断该界面是否需要显示输入法窗口。

其源代码释义如下:

[java] view plaincopyprint?
  1. /**
  2. * Interface passed to the keyguard view, for it to call up to control
  3. * its containing window.
  4. */
  5. public interface KeyguardWindowController {
  6. /** Control whether the window needs input -- that is if it has
  7. * text fields and thus should allow input method interaction. */
  8. void setNeedsInput(boolean needsInput); //是否需要显示输入法,为true表示需要。该方法可以想上层报到是否需要显示输入法窗口
  9. }

其唯一实现类是KeyguardViewManager类(稍后讲到)。

5、KeyguardViewManager


功能:包装了WindowManager功能了,提供了添加、删除锁屏界面的功能。

其源代码释义如下:

[java] view plaincopyprint?
  1. public class KeyguardViewManager implements KeyguardWindowController {
  2. ...
  3. private WindowManager.LayoutParams mWindowLayoutParams;
  4. private boolean mNeedsInput = false; //是否需要输入法 , 默认不需要
  5. private FrameLayout mKeyguardHost; //该ViewGroup作为顶层View,作为WindowManager添加至窗口
  6. private KeyguardViewBase mKeyguardView; //具体窗口内容。
  7. //以上两种的关系相当于DecorView和我们Activity内设置的资源文件一样
  8. private boolean mScreenOn = false; //是否处于亮屏状态
  9. //构造函数,初始化各种属性
  10. public KeyguardViewManager(Context context, ViewManager viewManager,
  11. KeyguardViewCallback callback, KeyguardViewProperties keyguardViewProperties, KeyguardUpdateMonitor updateMonitor) {
  12. ...
  13. }
  14. /**
  15. * Helper class to host the keyguard view.
  16. */
  17. private static class KeyguardViewHost extends FrameLayout {
  18. ... //KeyguardViewHost类
  19. }
  20. /**
  21. * Show the keyguard. Will handle creating and attaching to the view manager
  22. * lazily.
  23. */ //显示锁屏界面
  24. public synchronized void show() {
  25. if (mKeyguardHost == null) {
  26. ...
  27. mViewManager.addView(mKeyguardHost, lp);
  28. }
  29. if (mKeyguardView == null) {
  30. ...
  31. mKeyguardHost.addView(mKeyguardView, lp);
  32. if (mScreenOn) {
  33. mKeyguardView.onScreenTurnedOn();
  34. }
  35. }
  36. ...
  37. }
  38. ...
  39. /*** Hides the keyguard view */
  40. public synchronized void hide() { //隐藏锁屏界面,也就是说我们成功的解锁了
  41. if (mKeyguardHost != null) {
  42. mKeyguardHost.setVisibility(View.GONE);
  43. ...
  44. }
  45. }
  46. //锁屏界面是否处于显示状态
  47. public synchronized boolean isShowing() {
  48. return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
  49. }
  50. }
  51. }

6、 KeyguardUpdateMonitor.java类


功能:该类的主要功能就是根据监视系统状态值的改变(例如:时间、SIM卡状态、电池电量;使用广播监听),根据这种状态

值的改变回调监听了该状态信息的对象实例。

其源代码释义如下:

[java] view plaincopyprint?
  1. public class KeyguardUpdateMonitor {
  2. ...
  3. private int mFailedAttempts = 0; //当前登录事,已经失败的次数
  4. private ArrayList<InfoCallback> mInfoCallbacks; //保存所有监听对象 InfoCallback
  5. private ArrayList<SimStateCallback> mSimStateCallbacks ; //保存所有监听对象 SimStateCallback
  6. private static class SimArgs { //Sim状态信息
  7. ...
  8. }
  9. /**
  10. * Callback for general information relevant to lock screen.
  11. */
  12. interface InfoCallback {
  13. //电池电量信息改变:参数含义分别如下:是否显示电量信息 、 是否插入电影充电、 当前电池电量值
  14. void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel);
  15. void onTimeChanged(); //时间发生了改变
  16. //网络运营商状态发生了改变 ,例如从中国移动2G变为中国移动3G,或者无服务等 ;
  17. void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn);
  18. /** Called when the ringer mode changes. */
  19. void onRingerModeChanged(int state);
  20. /** 电话状态发生了改变 值可能为:EXTRA_STATE_IDLE、EXTRA_STATE_RINGING、EXTRA_STATE_OFFHOOK*/
  21. void onPhoneStateChanged(String newState);
  22. }
  23. /** Callback to notify of sim state change. */
  24. interface SimStateCallback {
  25. void onSimStateChanged(IccCard.State simState); //Sim卡信息发生了改变,例如有正常状况变为ABSENT/MISSING状态
  26. }
  27. /*** Register to receive notifications about general keyguard information
  28. * (see {@link InfoCallback}. */
  29. public void registerInfoCallback(InfoCallback callback) {
  30. if (!mInfoCallbacks.contains(callback)) {
  31. mInfoCallbacks.add(callback); //注册一个监听器
  32. } ...
  33. }
  34. ...
  35. }



7, LockPatternKeyguardView类 (自定义ViewGroup)

功能:作为LockScreen和UnLockScreen界面的载体,控制显示哪个界面。

其源代码释义如下:

[java] view plaincopyprint?
  1. public class LockPatternKeyguardView extends KeyguardViewBase {
  2. ...
  3. private View mLockScreen;
  4. private View mUnlockScreen;
  5. private boolean mScreenOn = false;//是否亮屏
  6. enum Mode {
  7. //当前显示界面的Mode Lock 或者UnLock
  8. }
  9. enum UnlockMode {
  10. ...//开锁界面的几种不同Mode
  11. }
  12. //构造函数
  13. public LockPatternKeyguardView( ...) {
  14. //KeyguardScreenCallback的实现对象
  15. mKeyguardScreenCallback = new KeyguardScreenCallback() {
  16. ...
  17. };
  18. ...
  19. }
  20. public void reset() {
  21. ...//重置显示界面
  22. }
  23. private void recreateLockScreen() {
  24. ...//重新构建LockScreen
  25. }
  26. private void recreateUnlockScreen() {
  27. ...//重新构建UnlockScreen
  28. }
  29. private void recreateScreens() {
  30. ...//重新构建该视图
  31. }
  32. public void verifyUnlock() {
  33. ...
  34. }
  35. public void cleanUp() {
  36. ... //清理资源对象
  37. }
  38. private boolean isSecure() {
  39. ...//手机设置是否处于安全状态
  40. }
  41. private void updateScreen(final Mode mode) {
  42. ...//根据参数(Lock/unLock),判断显示为LockScreen或者UnlockScreen界面
  43. }
  44. View createLockScreen() {
  45. ...//创建lockScreen
  46. }
  47. View createUnlockScreenFor(UnlockMode unlockMode) {
  48. ...//根据不同的Unlock Mode , 创建不同的UnlockScreen
  49. }
  50. private Mode getInitialMode() {
  51. ...//得到初始化的状态Mode (lock or unlock).
  52. }
  53. /** Given the current state of things, what should the unlock screen be? */
  54. private UnlockMode getUnlockMode() {
  55. ...//返回开锁的状态Unlock Mode
  56. }
  57. private void showTimeoutDialog() {
  58. ... //输入密码超过一定次数时,提示30s后在登录的对话框
  59. }
  60. private void showAlmostAtAccountLoginDialog() {
  61. ... //显示Google 账户登录对话框
  62. }
  63. }



8、KeyguardViewBase类 抽象类 (自定义ViewGroup)


功能:为LockPatternKeyguardView提供了一组通用的方法 。需要值得注意的方法就是他对某些KeyEvent的监听,

当他消费监听到这些KeyEvent,我们的App就监听不到这些KeyEvent了 。常用的有KEYEVENT_VOLUME_UP/DOWN等。

[java] view plaincopyprint?
  1. public abstract class KeyguardViewBase extends FrameLayout {
  2. ...
  3. @Override
  4. public boolean dispatchKeyEvent(KeyEvent event) {
  5. ...
  6. if (interceptMediaKey(event)) {
  7. return true;
  8. }
  9. return super.dispatchKeyEvent(event);
  10. }
  11. private boolean interceptMediaKey(KeyEvent event) {
  12. final int keyCode = event.getKeyCode();
  13. if (event.getAction() == KeyEvent.ACTION_DOWN) {
  14. switch (keyCode) {
  15. ...//more keyevent
  16. case KeyEvent.KEYCODE_VOLUME_UP:
  17. case KeyEvent.KEYCODE_VOLUME_DOWN: {
  18. ...
  19. // Don't execute default volume behavior
  20. return true; //直接返回不在向下传递处理
  21. }
  22. }
  23. }
  24. return false;
  25. }
  26. }

9、 KeyguardViewProperties.java 接口

功能:提供了创建界面的通用方法。

[java] view plaincopyprint?
  1. public interface KeyguardViewProperties {
  2. //创建一个KeyguardViewBase实例 , 实际是指LockPatternKeyguardView实例
  3. KeyguardViewBase createKeyguardView(Context context,
  4. KeyguardUpdateMonitor updateMonitor,
  5. KeyguardWindowController controller);
  6. boolean isSecure();
  7. }

其唯一实现类是是LockPatternKeyguardViewProperties类(稍后讲到)。


10、LockPatternKeyguardViewProperties

源代码释义如下:

[java] view plaincopyprint?
  1. public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {
  2. ...
  3. //创建一个LockPatternKeyguardView对象
  4. public KeyguardViewBase createKeyguardView(Context context,
  5. KeyguardUpdateMonitor updateMonitor,
  6. KeyguardWindowController controller) {
  7. return new LockPatternKeyguardView(context, updateMonitor,
  8. mLockPatternUtils, controller);
  9. }
//=============================================

// OK ,我知道你看的很纠结了,具体需要时参考源代码看是最明智的。

//=============================================


我知道代码贴的太多了,没办法,谁让它理解起来就那么费劲呢 ? 你可别犯愁,真正核心的类可还没出来。。


12、KeyguardViewMediator核心类 ,该类是唯一实现了KeyguardViewCallback的类。

功能: 功能:该类提供了一些接口,由PhoneWindowManager)去访问控制Keyguard....

该类的初始化是在PolicyWindowManager的构造函数中创建的。如下:

[java] view plaincopyprint?
  1. public class PhoneWindowManager implements WindowManagerPolicy {
  2. ...
  3. /** {@inheritDoc} */ //由SystemServer调用
  4. public void init(Context context, IWindowManager windowManager,
  5. LocalPowerManager powerManager) {
  6. ...//初始化该实例
  7. mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager);
  8. }
  9. }

参照源代码,把一些重要的属性和方法的大意给分析下:

[java] view plaincopyprint?
  1. public class KeyguardViewMediator implements KeyguardViewCallback, KeyguardUpdateMonitor.SimStateCallback {
  2. private boolean mSystemReady; //启动成功 由SystemServer调用
  3. /**Used to keep the device awake while to ensure the keyguard finishes opening before
  4. * we sleep.*/ //在需要显示锁屏界面时,保持屏幕在某个时间段内为暗屏状态
  5. private PowerManager.WakeLock mShowKeyguardWakeLock;
  6. private KeyguardViewManager mKeyguardViewManager; //KeyguardViewManager实例
  7. /** * External apps (like the phone app) can tell us to disable the keygaurd.*/
  8. //是否允许其他App禁止锁屏 , 例如来电时 禁止锁屏
  9. private boolean mExternallyEnabled = true;
  10. //处于锁屏状态 , 即显示锁屏
  11. private boolean mShowing = false;
  12. // true if the keyguard is hidden by another window
  13. private boolean mHidden = false; //被其他窗口掩盖 , 例如来电时锁屏被掩盖
  14. private boolean mScreenOn = false; // 是否亮屏
  15. public KeyguardViewMediator(Context context, PhoneWindowManager callback,
  16. LocalPowerManager powerManager) {
  17. ...
  18. //构造相关实例对象
  19. mKeyguardViewProperties = new LockPatternKeyguardViewProperties(
  20. new LockPatternUtils(mContext), mUpdateMonitor);
  21. mKeyguardViewManager = new KeyguardViewManager(
  22. context, WindowManagerImpl.getDefault(), this,
  23. mKeyguardViewProperties, mUpdateMonitor);
  24. //解锁成功后发送的Intent
  25. mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
  26. mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
  27. }
  28. /** Called to let us know the screen was turned off.
  29. * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
  30. * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
  31. * {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
  32. */
  33. //屏幕变灰暗 , 原因有如下:以及对应的逻辑处理。
  34. // 1、OFF_BECAUSE_OF_USER : 用户按下POWER键 , 当前是否处于锁屏界面,若是(mShowing)则重置显示界面,否则重新显示锁屏界面
  35. // 2、OFF_BECAUSE_OF_TIMEOUT : 屏幕超时,常见情况就是一段时间没有操作屏幕,手机处于灰暗状态。 处理行为:
  36. // 发送Action值为DELAYED_KEYGUARD_ACTION的广播,因为该类注册了该Intent广播,接受到时会调用doKeyguard()方法锁屏
  37. // 3、OFF_BECAUSE_OF_PROX_SENSOR:接打电话时,距离感应太近导致暗屏,此时由于PowerManager那儿已经处理了暗屏,不需要做任何事
  38. // 最后,如果以上逻辑都不成立,调用 doKeyguard()方法显示屏幕
  39. public void onScreenTurnedOff(int why) {
  40. ...
  41. }
  42. /**
  43. * Let's us know the screen was turned on.
  44. */
  45. public void onScreenTurnedOn() {
  46. synchronized (this) {
  47. ...
  48. notifyScreenOnLocked(); //通知亮屏
  49. }
  50. }
  51. /** Enable the keyguard if the settings are appropriate. */
  52. private void doKeyguard() {
  53. synchronized (this) {
  54. ...
  55. showLocked();//显示锁屏界面
  56. }
  57. }
  58. //该方法的调用时机就是当按下POWER键时,系统会回调该方法 keyCode值一般为 26
  59. public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode) {
  60. //操作按键是否能唤醒屏幕
  61. if (isWakeKeyWhenKeyguardShowing(keyCode)) {
  62. // give the keyguard view manager a chance to adjust the state of the
  63. // keyguard based on the key that woke the device before poking
  64. // the wake lock
  65. wakeWhenReadyLocked(keyCode);//开始唤醒屏幕咯
  66. return true;
  67. } else {
  68. return false;
  69. }
  70. }
  71. /** {@inheritDoc} */ //在一定时间内保存屏幕为亮屏状态
  72. public void pokeWakelock(int holdMs) {
  73. ...
  74. }
  75. //表示成功得分完成了解锁操作
  76. public void keyguardDone(boolean authenticated, boolean wakeup) {
  77. synchronized (this) {
  78. //发送给Handler 进行异步处理
  79. Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
  80. msg.arg1 = wakeup ? 1 : 0;
  81. mHandler.sendMessage(msg);
  82. if (authenticated) {
  83. mUpdateMonitor.clearFailedAttempts(); //清除错误登录次数
  84. }
  85. ...
  86. }
  87. }
  88. //Handler对象 , 异步处理
  89. private Handler mHandler = new Handler() {
  90. @Override
  91. public void handleMessage(Message msg) {
  92. switch (msg.what) {
  93. ... //异步处理
  94. }
  95. }
  96. };
  97. //异步处理完成开锁成功
  98. private void handleKeyguardDone(boolean wakeup) {
  99. handleHide(); //释放该Keyguard对应的窗口
  100. mWakeLock.release();
  101. mContext.sendBroadcast(mUserPresentIntent); //解锁成功,发送Intent信息
  102. }
  103. //显示锁屏界面
  104. private void handleShow() {
  105. synchronized (KeyguardViewMediator.this) {
  106. ...
  107. mKeyguardViewManager.show();
  108. mShowing = true;
  109. ...
  110. }
  111. }
  112. private void handleHide() {
  113. synchronized (KeyguardViewMediator.this) {
  114. //去除锁屏界面对应的窗口
  115. mKeyguardViewManager.hide();
  116. mShowing = false;
  117. ...
  118. }
  119. }
  120. //设置状态栏enable状态 , 例如:能否被下拉等
  121. private void adjustStatusBarLocked() {
  122. ...
  123. // if the keyguard is shown, allow the status bar to open
  124. // only if the keyguard is insecure and is covered by another window
  125. boolean enable = !mShowing || (mHidden && !isSecure());
  126. mStatusBarManager.disable(enable ?StatusBarManager.DISABLE_NONE : StatusBarManager.DISABLE_EXPAND);
  127. }
  128. }
  129. }

该类的很多方法都是由PhoneWindowManager调用访问的。

























LockScreen具体流程可见顶部的文章

分析以下MultiWaveView.java这个类,其实看java代码先看类的写法,看类继承了哪些类,实现了哪些接口,这样心理就有个大概了,大概就知道代码会走哪些方法了。

public class MultiWaveView extends View {

public class MultiWaveView extends View {

其实这个类就是一个view类;


再来看看这个类中有没有内部类,或者内部接口什么的?

大致浏览以下发现这个类中有内部接口:

public interface OnTriggerListener { int NO_HANDLE = 0; int CENTER_HANDLE = 1; public void onGrabbed(View v, int handle); public void onReleased(View v, int handle); public void onTrigger(View v, int target); public void onGrabbedStateChange(View v, int handle); }


通过单词的翻译大概就了解这些方法的作用了,

onGrabbed():抓起handler的触发方法; onReleased():释放handler的触发方法;

onTrigger():触发方法,就是最后滑动到哪个app了,就会回调这个方法;

private static final int STATE_IDLE = 0; private static final int STATE_FIRST_TOUCH = 1; private static final int STATE_TRACKING = 2; private static final int STATE_SNAP = 3; private static final int STATE_FINISH = 4;

onTouchEvent中的handleMove():


在handleMove()方法中——>trySwitchToFirstTouchState(event);——>switchToState()——>doFinish();

——>setGrabbedState() ————> mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState);

设置回调。

LockScreen详细实现的介绍可见头部文章。

读书人网 >Android

热点推荐