锁屏界面的加载通常在android中有两种方式触发:android系统开机和screenOff(灭屏)后,再screenOn;

先来看

android系统开机时候的锁屏加载流程:
首先在系统启动过程中,会进入到SystemServer.java的startOtherServices()方法:

初始化WindowManagerService;

[java] view plain copy
  1. wm = WindowManagerService.main(context, inputManager,
  2. mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
  3. !mFirstBoot, mOnlyCore);

调用systemReady()方法,表示系统准备启动;

[java] view plain copy
  1. try {
  2. wm.systemReady();
  3. } catch (Throwable e) {
  4. reportWtf("making Window Manager Service ready", e);
  5. }

调用WindowManagerPolicy.java的systemReady()方法

[java] view plain copy
  1. public void systemReady() {
  2. mPolicy.systemReady();
  3. }

而这个mPolicy 是由PhoneWindowManager.java的构造方法构造出来的;

[java] view plain copy
  1. final WindowManagerPolicy mPolicy = new PhoneWindowManager();

也就是说最终会调用到PhoneWindowManager.java的systemReady()方法,在这个方法内初始化KeyguardServiceDelegate对象并调用systemReady()方法;

[java] view plain copy
  1. mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
  2. mKeyguardDelegate.onSystemReady();

在KeyguardServiceDelegate.java类内,继续调用KeyguardServiceWrapper.java的systemReady()方法;

[java] view plain copy
  1. public void onSystemReady() {
  2. if (mKeyguardService != null) {
  3. mKeyguardService.onSystemReady();
  4. } else {
  5. mKeyguardState.systemIsReady = true;
  6. }
  7. }

在KeyguardServiceWrapper.java内使用aidl调用KeyguardService.java的onSystemReady()方法;

[java] view plain copy
  1. @Override // Binder interface
  2. public void onSystemReady() {
  3. try {
  4. mService.onSystemReady();
  5. } catch (RemoteException e) {
  6. Slog.w(TAG , "Remote Exception", e);
  7. }
  8. }

在KeyguardService.java内调用KeyguardViewMediator.java的onSystemReady()方法;

[java] view plain copy
  1. @Override // Binder interface
  2. public void onSystemReady() {
  3. checkPermission();
  4. mKeyguardViewMediator.onSystemReady();
  5. }

最终在KeyguardViewMediator.java的onSystemReady()方法内调用doKeyguardLocked()开始锁屏加载流程;

[java] view plain copy
  1. /**
  2. * Let us know that the system is ready after startup.
  3. */
  4. public void onSystemReady() {
  5. mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
  6. synchronized (this) {
  7. if (DEBUG) Log.d(TAG, "onSystemReady");
  8. mSystemReady = true;
  9. doKeyguardLocked(null);
  10. mUpdateMonitor.registerCallback(mUpdateCallback);
  11. }
  12. // Most services aren't available until the system reaches the ready state, so we
  13. // send it here when the device first boots.
  14. maybeSendUserPresentBroadcast();
  15. }

KeyguardViewMediator.java的doKeyguardLocked()方法;

[java] view plain copy
  1. /**
  2. * Enable the keyguard if the settings are appropriate.
  3. */
  4. private void doKeyguardLocked(Bundle options) {
  5. // if another app is disabling us, don't show
  6. if (!mExternallyEnabled) {
  7. return;
  8. }
  9. // if the keyguard is already showing, don't bother
  10. if (mStatusBarKeyguardViewManager.isShowing()) {
  11. resetStateLocked();
  12. return;
  13. }
  14. // if the setup wizard hasn't run yet, don't show
  15. final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
  16. final boolean absent = SubscriptionManager.isValidSubscriptionId(
  17. mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.ABSENT));
  18. final boolean disabled = SubscriptionManager.isValidSubscriptionId(
  19. mUpdateMonitor.getNextSubIdForState(IccCardConstants.State.PERM_DISABLED));
  20. final boolean lockedOrMissing = mUpdateMonitor.isSimPinSecure()
  21. || ((absent || disabled) && requireSim);
  22. if (!lockedOrMissing && shouldWaitForProvisioning()) {
  23. return;
  24. }
  25. if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
  26. && !lockedOrMissing) {
  27. return;
  28. }
  29. if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
  30. // Without this, settings is not enabled until the lock screen first appears
  31. setShowingLocked(false);
  32. hideLocked();
  33. mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
  34. return;
  35. }
  36. showLocked(options);
  37. }

1、mExternallyEnabled;默认为true,如果其它应用设置keyguard不显示,则直接return不显示;
2、如果keyguard当前正在显示,则不用管它,重置;
3、如果安装向导未执行完毕,即设备未完成初始化绑定等操作,也不去显示keyguard;
4、如果当前屏幕为灭屏状态,也不去显示keyguard;
5、Without this, settings is not enabled until the lock screen first appears(我这边没有比较好的说法);
6、如果上述条件都不满足则使用showLocked()方法开始显示keyguard。

发送msg为SHOW的消息,开始显示keyguard;

[java] view plain copy
  1. /**
  2. * Send message to keyguard telling it to show itself
  3. * @see #handleShow
  4. */
  5. private void showLocked(Bundle options) {
  6. if (DEBUG) Log.d(TAG, "showLocked");
  7. // ensure we stay awake until we are finished displaying the keyguard
  8. mShowKeyguardWakeLock.acquire();
  9. Message msg = mHandler.obtainMessage(SHOW, options);
  10. mHandler.sendMessage(msg);
  11. }

调用handleShow()方法;

[java] view plain copy
  1. case SHOW:
  2. handleShow((Bundle) msg.obj);
  3. break;

在handleShow()方法中调用StatusBarKeyguardViewManager.java的show()方法;

[java] view plain copy
  1. /**
  2. * Handle message sent by {@link #showLocked}.
  3. * @see #SHOW
  4. */
  5. private void handleShow(Bundle options) {
  6. synchronized (KeyguardViewMediator.this) {
  7. if (!mSystemReady) {
  8. if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
  9. return;
  10. } else {
  11. if (DEBUG) Log.d(TAG, "handleShow");
  12. }
  13. setShowingLocked(true);
  14. mStatusBarKeyguardViewManager.show(options);
  15. mHiding = false;
  16. mWakeAndUnlocking = false;
  17. resetKeyguardDonePendingLocked();
  18. mHideAnimationRun = false;
  19. updateActivityLockScreenState();
  20. adjustStatusBarLocked();
  21. userActivity();
  22. mShowKeyguardWakeLock.release();
  23. }
  24. mKeyguardDisplayManager.show();
  25. }

调入到StatusBarKeyguardViewManager.java的show()方法

[java] view plain copy
  1. public void show(Bundle options) {
  2. mShowing = true;
  3. mStatusBarWindowManager.setKeyguardShowing(true);
  4. mScrimController.abortKeyguardFadingOut();
  5. reset();
  6. }

StatusBarKeyguardViewManager.java负责keyguard在status bar中创建、显示、隐藏、重置
StatusBarWindowManager.java负责所有的status bar窗口状态的逻辑管理
1、StatusBarKeyguardViewManager.java的setKeyguardShowing()方法去使用apply()方法刷新mStatusBarView的flag参数;

[java] view plain copy
  1. public void setKeyguardShowing(boolean showing) {
  2. mCurrentState.keyguardShowing = showing;
  3. apply(mCurrentState);
  4. }

2、调用reset()方法去重置mStatusBarView的state,先来看reset()方法;

[java] view plain copy
  1. /**
  2. * Reset the state of the view.
  3. */
  4. public void reset() {
  5. if (mShowing) {
  6. if (mOccluded) {
  7. mPhoneStatusBar.hideKeyguard();
  8. mPhoneStatusBar.stopWaitingForKeyguardExit();
  9. mBouncer.hide(false /* destroyView */);
  10. } else {
  11. showBouncerOrKeyguard();
  12. }
  13. KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
  14. updateStates();
  15. }
  16. }

在reset()方法中会去判断keyguard是否被其它的窗口中断mOccluded,是则不显示keyguard;否则的就执行showBouncerOrKeyguard()方法;
showBouncerOrKeyguard()方法使用KeyguardBouncer.java的needsFullscreenBouncer()方法判断显示常规锁屏还是Bouncer安全锁屏(比如图案锁屏、密码锁屏、PIN码锁屏等);

[java] view plain copy
  1. /**
  2. * Shows the notification keyguard or the bouncer depending on
  3. * {@link KeyguardBouncer#needsFullscreenBouncer()}.
  4. */
  5. private void showBouncerOrKeyguard() {
  6. if (mBouncer.needsFullscreenBouncer()) {
  7. // The keyguard might be showing (already). So we need to hide it.
  8. mPhoneStatusBar.hideKeyguard();
  9. mBouncer.show(true /* resetSecuritySelection */);
  10. } else {
  11. mPhoneStatusBar.showKeyguard();
  12. mBouncer.hide(false /* destroyView */);
  13. mBouncer.prepare();
  14. }
  15. }

1、常规锁屏即为滑动锁屏界面,一般滑动即可解锁,称之为notification keyguard;这个类型的keyguard已经和statusbar融为一体了,可以通过PhoneStatusBar.java的对象直接进行控制;
2、Bouncer安全锁屏;比如密码、图案、PIM码、PUK码等锁屏方式的锁屏界面,通过KeyguardBouncer.java来开始控制show()和hide();

[java] view plain copy
  1. KeyguardBouncer.java的show()方法:
  2. public void show(boolean resetSecuritySelection) {
  3. ensureView();
  4. if (resetSecuritySelection) {
  5. // showPrimarySecurityScreen() updates the current security method. This is needed in
  6. // case we are already showing and the current security method changed.
  7. mKeyguardView.showPrimarySecurityScreen();
  8. }
  9. if (mRoot.getVisibility() == View.VISIBLE || mShowingSoon) {
  10. return;
  11. }
  12. // Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole
  13. // Keyguard. If we need to authenticate, show the bouncer.
  14. if (!mKeyguardView.dismiss()) {
  15. mShowingSoon = true;
  16. // Split up the work over multiple frames.
  17. DejankUtils.postAfterTraversal(mShowRunnable);
  18. }
  19. }

1、首先调用ensureView()方法去加载keyguard_bouncer view

[java] view plain copy
  1. private void ensureView() {
  2. if (mRoot == null) {
  3. inflateView();
  4. }
  5. }
  6. private void inflateView() {
  7. removeView();
  8. mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
  9. mKeyguardView = (KeyguardHostView) mRoot.findViewById(R.id.keyguard_host_view);
  10. mKeyguardView.setLockPatternUtils(mLockPatternUtils);
  11. mKeyguardView.setViewMediatorCallback(mCallback);
  12. mContainer.addView(mRoot, mContainer.getChildCount());
  13. mRoot.setVisibility(View.INVISIBLE);
  14. mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
  15. }

2、调用KeyguardHostView.java的showPrimarySecurityScreen()方法;

[java] view plain copy
  1. /**
  2. * Called when the view needs to be shown.
  3. */
  4. public void showPrimarySecurityScreen() {
  5. if (DEBUG) Log.d(TAG, "show()");
  6. mSecurityContainer.showPrimarySecurityScreen(false);
  7. }

继续调用KeyguardSecurityContainer.java的showPrimarySecurityScreen()方法,先去获取锁屏方式;

[java] view plain copy
  1. /**
  2. * Shows the primary security screen for the user. This will be either the multi-selector
  3. * or the user's security method.
  4. * @param turningOff true if the device is being turned off
  5. */
  6. void showPrimarySecurityScreen(boolean turningOff) {
  7. SecurityMode securityMode = mSecurityModel.getSecurityMode();
  8. if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
  9. showSecurityScreen(securityMode);
  10. }

继续往下将获取到的锁屏方式securityMode作为参数调用showSecurityScreen()方法;这个方法主要是用来根据securityMode显示锁屏view的。

[java] view plain copy
  1. /**
  2. * Switches to the given security view unless it's already being shown, in which case
  3. * this is a no-op.
  4. *
  5. * @param securityMode
  6. */
  7. private void showSecurityScreen(SecurityMode securityMode) {
  8. if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
  9. if (securityMode == mCurrentSecuritySelection) return;
  10. KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
  11. KeyguardSecurityView newView = getSecurityView(securityMode);
  12. // Emulate Activity life cycle
  13. if (oldView != null) {
  14. oldView.onPause();
  15. oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
  16. }
  17. if (securityMode != SecurityMode.None) {
  18. newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
  19. newView.setKeyguardCallback(mCallback);
  20. }
  21. // Find and show this child.
  22. final int childCount = mSecurityViewFlipper.getChildCount();
  23. final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
  24. for (int i = 0; i < childCount; i++) {
  25. if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {
  26. mSecurityViewFlipper.setDisplayedChild(i);
  27. break;
  28. }
  29. }
  30. mCurrentSecuritySelection = securityMode;
  31. mSecurityCallback.onSecurityModeChanged(securityMode,
  32. securityMode != SecurityMode.None && newView.needsInput());
  33. }

1、首先判断传入进来的securityMode是否已经被显示;
2、调用getSecurityView()方法获取给定的锁屏view;
3、调用KeyguardSecurityView.java的onPause()方法暂停显示旧锁屏view,onResume()方法开始显示新的锁屏view;KeyguardSecurityView.java是一个接口类,其内部方法都是抽象的只有声明没有实现,其方法实现都是在继承于这个接口的类中。
而在keyguard中主要是KeyguardAbsKeyInputView.java、KeyguardPasswordView.java、KeyguardPatternView.java等等这些类继承于此接口实现其内部方法,这些类就是具体的锁屏界面view显示;

开机显示keyguard的总结:
1、在KeyguardViewMediator.java的onSystemReady()方法内调用doKeyguardLocked()开始锁屏加载流程;
2、setKeyguardEnabled();其他应用程序或者服务可以调用setKeyguardEnabled()方法请求禁止锁屏;
3、KeyguardViewMediator.java在keyguard中起着主要调度的作用,主要负责
1)查询锁屏状态,当前是锁屏还是解锁状态;在锁屏状态下,会限制输入事件。
2)PhoneWindowManager.java通过mKeyguardDelegate对象(KeyguardServiceDelegate.java)来使能KeyguardViewMediator.java,调用其中的方法;
3)响应SIM卡状态变化并对锁屏界面做相应的调整onSimStateChanged();
4、判断keyguard是否被禁止、keyguard当前是否正在显示等等即当前是否可以显示keguard,可以显示的话继续调用showLocked()方法;
5、调用handleShow()方法,调用StatusBarKeyguardViewManager.java的show()开始显示keyguard锁屏界面;
6、调用reset()方法,调用showBouncerOrKeyguard()方法判断是显示正常锁屏界面还是安全锁屏界面;显示正常锁屏的话直接调用PhoneStatusBar.java的showKeyguard()或者hideKeyguard()方法;如果显示安全锁屏界面的话则调入KeyguardBouncer.java类内;
7、调用KeyguardBouncer.java的show()方法;使用ensureView()方法去加载实例化布局;调用KeyguardHostView.java的showPrimarySecurityScreen()方法去显示安全锁屏界面;
8、KeyguardHostView.java的showPrimarySecurityScreen()方法会调入到KeyguardSecurityContainer.java的showPrimarySecurityScreen()方法中来;
9、调用showSecurityScreen()方法,根据锁屏方式来加载不同的锁屏view;
10、KeyguardSecurityView.java是一个接口类,其内部方法都是抽象的只有声明没有实现,其方法实现都是在继承于这个接口的类中。
而在keyguard中主要是KeyguardAbsKeyInputView.java、KeyguardPasswordView.java、KeyguardPatternView.java等等Keyguard*View.java这些类继承于此接口实现其内部方法,这些类就是具体的锁屏界面view显示;

系统灭屏Screen off之后的keguard加载流程:
android系统中的自动灭屏跟Power按键之后灭屏流程可能有点区别,但是由于主要是分析灭屏之后keyguard加载,所以只需要关心keguard在系统灭屏之后的加载流程。
这里以按power键灭屏为例,分析其流程:
当亮屏状态下Power键按下之后,经过一系列的判断之后会调用mPowerManager.goToSleep()方法,即通过aidl调用到PowerManagerService.java的gotoSleep()方法:

[java] view plain copy
  1. @Override // Binder call
  2. public void goToSleep(long eventTime, int reason, int flags) {
  3. if (eventTime > SystemClock.uptimeMillis()) {
  4. throw new IllegalArgumentException("event time must not be in the future");
  5. }
  6. mContext.enforceCallingOrSelfPermission(
  7. android.Manifest.permission.DEVICE_POWER, null);
  8. final int uid = Binder.getCallingUid();
  9. final long ident = Binder.clearCallingIdentity();
  10. try {
  11. goToSleepInternal(eventTime, reason, flags, uid);
  12. } finally {
  13. Binder.restoreCallingIdentity(ident);
  14. }
  15. }

继续调用goToSleepInternal()方法:

[java] view plain copy
  1. private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
  2. synchronized (mLock) {
  3. if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
  4. updatePowerStateLocked();
  5. }
  6. }
  7. }

调用updatePowerStateLocked()方法,在这个方法内又去调用finishWakefulnessChangeIfNeededLocked()方法

[java] view plain copy
  1. private void finishWakefulnessChangeIfNeededLocked() {
  2. if (mWakefulnessChanging && mDisplayReady) {
  3. if (mWakefulness == WAKEFULNESS_DOZING
  4. && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
  5. return; // wait until dream has enabled dozing
  6. }
  7. mWakefulnessChanging = false;
  8. mNotifier.onWakefulnessChangeFinished();
  9. }
  10. }

此时调用Notifier.java的onWakefulnessChangeFinished()方法:

[java] view plain copy
  1. /**
  2. * Notifies that the device has finished changing wakefulness.
  3. */
  4. public void onWakefulnessChangeFinished() {
  5. if (DEBUG) {
  6. Slog.d(TAG, "onWakefulnessChangeFinished");
  7. }
  8. if (mInteractiveChanging) {
  9. mInteractiveChanging = false;
  10. handleLateInteractiveChange();
  11. }
  12. }

调用handleLateInteractiveChange()方法;

[java] view plain copy
  1. /**
  2. * Handle late interactive state changes once they are finished so that the system can
  3. * finish pending transitions (such as turning the screen off) before causing
  4. * applications to change state visibly.
  5. */
  6. private void handleLateInteractiveChange() {
  7. synchronized (mLock) {
  8. if (mInteractive) {
  9. // Finished waking up...
  10. mHandler.post(new Runnable() {
  11. @Override
  12. public void run() {
  13. mPolicy.finishedWakingUp();
  14. }
  15. });
  16. } else {
  17. // Finished going to sleep...
  18. // This is a good time to make transitions that we don't want the user to see,
  19. // such as bringing the key guard to focus.  There's no guarantee for this
  20. // however because the user could turn the device on again at any time.
  21. // Some things may need to be protected by other mechanisms that defer screen on.
  22. // Cancel pending user activity.
  23. if (mUserActivityPending) {
  24. mUserActivityPending = false;
  25. mHandler.removeMessages(MSG_USER_ACTIVITY);
  26. }
  27. // Tell the policy we finished going to sleep.
  28. final int why = translateOffReason(mInteractiveChangeReason);
  29. mHandler.post(new Runnable() {
  30. @Override
  31. public void run() {
  32. EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
  33. mPolicy.finishedGoingToSleep(why);
  34. }
  35. });
  36. // Send non-interactive broadcast.
  37. mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
  38. mPendingGoToSleepBroadcast = true;
  39. updatePendingBroadcastLocked();
  40. }
  41. }
  42. }

这个方法里面需要关注的有两句话:mPolicy.finishedWakingUp()和mPolicy.finishedGoingToSleep();看其中的注释发现一个是唤醒另外一个是睡眠操作,由于当前是power灭屏,所以需要看得是mPolicy.finishedGoingToSleep()方法。而mPolicy是WindowManagerPolicy.java的对象,这个类又是一个接口类,接口实现是在PhoneWindowManager.java类中,故此时调入到PhoneWindowManager.java的finishedGoingToSleep()方法;

[java] view plain copy
  1. // Called on the PowerManager's Notifier thread.
  2. @Override
  3. public void finishedGoingToSleep(int why) {
  4. EventLog.writeEvent(70000, 0);
  5. if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
  6. MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
  7. // We must get this work done here because the power manager will drop
  8. // the wake lock and let the system suspend once this function returns.
  9. synchronized (mLock) {
  10. mAwake = false;
  11. updateWakeGestureListenerLp();
  12. updateOrientationListenerLp();
  13. updateLockScreenTimeout();
  14. }
  15. if (mKeyguardDelegate != null) {
  16. mKeyguardDelegate.onFinishedGoingToSleep(why);
  17. }
  18. }

分析这个方法看到这么一句话:

[java] view plain copy
  1. mKeyguardDelegate.onFinishedGoingToSleep(why);

也就是说会调用KeyguardServiceDelegate.java的onFinishedGoingToSleep()方法;而在上面的分析过程中知道,PhoneWindowManager.java通过mKeyguardDelegate对象(KeyguardServiceDelegate.java)来使能KeyguardViewMediator.java,调用其中的方法;也就是说通过这句话此时逻辑已经调入到了KeyguardViewMediator.java类的onFinishedGoingToSleep()方法。

[java] view plain copy
  1. public void onFinishedGoingToSleep(int why) {
  2. if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")");
  3. synchronized (this) {
  4. mDeviceInteractive = false;
  5. mGoingToSleep = false;
  6. resetKeyguardDonePendingLocked();
  7. mHideAnimationRun = false;
  8. notifyFinishedGoingToSleep();
  9. if (mPendingReset) {
  10. resetStateLocked();
  11. mPendingReset = false;
  12. }
  13. if (mPendingLock) {
  14. doKeyguardLocked(null);
  15. mPendingLock = false;
  16. }
  17. }
  18. KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why);
  19. }

在这个方法中调用notifyFinishedGoingToSleep()方法,向mHandler中发送一个msg为NOTIFY_FINISHED_GOING_TO_SLEEP的消息;

[java] view plain copy
  1. private void notifyFinishedGoingToSleep() {
  2. if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep");
  3. mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP);
  4. }

mHandler收到这个消息后,去调用handleNotifyFinishedGoingToSleep()方法;

[java] view plain copy
  1. case NOTIFY_FINISHED_GOING_TO_SLEEP:
  2. handleNotifyFinishedGoingToSleep();
  3. break;

在这个方法中去调用StatusBarKeyguardViewManager.java的onFinishedGoingToSleep()方法;

[java] view plain copy
  1. private void handleNotifyFinishedGoingToSleep() {
  2. synchronized (KeyguardViewMediator.this) {
  3. if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
  4. mStatusBarKeyguardViewManager.onFinishedGoingToSleep();
  5. }
  6. }

再来看StatusBarKeyguardViewManager.java的onFinishedGoingToSleep()方法:

[java] view plain copy
  1. public void onFinishedGoingToSleep() {
  2. mDeviceInteractive = false;
  3. mPhoneStatusBar.onFinishedGoingToSleep();
  4. mBouncer.onScreenTurnedOff();
  5. }

1、调用PhoneStatusBar.java的onFinishedGoingToSleep(),去通知PhoneStatusBar更新当前的状态;
2、进入KeyguardBouncer.java的onScreenTurnedOff()方法真正开始keyguard的加载;

接下来来看KeyguardBouncer.java的onScreenTurnedOff()方法:

[java] view plain copy
  1. public void onScreenTurnedOff() {
  2. if (mKeyguardView != null && mRoot != null && mRoot.getVisibility() == View.VISIBLE) {
  3. mKeyguardView.onPause();
  4. }
  5. }

调用KeyguardHostView.java的onPause()方法:

[java] view plain copy
  1. /**
  2. * Called when the Keyguard is not actively shown anymore on the screen.
  3. */
  4. public void onPause() {
  5. if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
  6. Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
  7. mSecurityContainer.showPrimarySecurityScreen(true);
  8. mSecurityContainer.onPause();
  9. clearFocus();
  10. }

继续调用KeyguardSecurityContainer.java的showPrimarySecurityScreen()方法,根据上面的分析知道,此处先会去获取当前锁屏方式,然后根据得到的锁屏方式去加载锁屏界面;
至此完成keyguard在screen off状态下的加载流程分析;

正常灭屏显示keyguard流程总结:
1、不管是按Power键还是自动灭屏,都会执行到PowerManagerService.java的gotoSleep()方法;
2、在这个方法内通过一系列的调用,调入到PhoneWindowManager.java的finishedGoingToSleep()方法;
3、在PhoneWindowManager.java类中通过KeyguardServiceDelegate.java类的对象mKeyguardDelegate来使能KeyguardViewMediator.java;
4、而KeyguardViewMediator.java作为keyguard的调度者,从这里开始keyguard的加载;
5、最终在KeyguardSecurityContainer.java的showPrimarySecurityScreen()方法内去实现根据锁屏方式加载锁屏界面;

原文地址: http://blog.csdn.net/Otaku_627/article/details/53769473?locationNum=5&fps=1

Android6.0 keyguard锁屏加载流程分析相关推荐

  1. android app启动流程分析,Android应用开发之Android 7.0 Launcher3的启动和加载流程分析...

    本文将带你了解Android应用开发Android 7.0 Launcher3的启动和加载流程分析,希望本文对大家学Android有所帮助. Android 7.0 Launcher3的启动和加载流程 ...

  2. Android 7.0 Launcher3的启动和加载流程分析----转载

     Android 7.0 Launcher3的启动和加载流程分析,Launcher的本质就是一个普通应用,它比普通应用多配置了Category的Android:name="android ...

  3. Launcher3 桌面加载流程分析

    Launcher3 桌面加载流程分析 主入口Launcher 首先来看Launcher.java的onCreate方法,里面代码很多,只看主流程部分: @Override protected void ...

  4. linux驱动加载流程分析

    linux驱动加载流程分析 内核是如何加载驱动的,有些是编译到内核里面,有些事编译成ko,让系统自动加载.总的说来,在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动 ...

  5. MultiDex加载流程分析

    MultiDex加载流程分析 只介绍主要流程,multiDex源码已经上传到https://github.com/AlexSmille/google-android-support-source-an ...

  6. Spring初始化加载流程分析

    关于Spring框架的介绍,网上有很多非常好的详细的文章,如果在本篇博客中没有了解到自己想要的东西,个人能力有限,只能使用博客记录一下自己目前了解的知识点了! 本篇博客将大致介绍一下Spring框架的 ...

  7. Android 4.0 ICS SystemUI浅析——StatusBar加载流程分析

    前面两篇文章< Android 4.0 ICS SystemUI浅析--SystemUI启动流程>.< Android 4.0 ICS SystemUI浅析--StatusBar结构 ...

  8. Pinpoint Agent加载流程分析

    pinpoint 版本:2.0.3-SNAPSHOT pinpoint利用java agent 特性,提供了一个agent jar包,此jar包会在应用运行之前先运行,agent和应用在同一个进程.p ...

  9. 安卓锁屏灭屏加载流程

    时间2022-01-10 相关的类 首先需要了解以下这几个类 KeyguardViewMeditor:整个锁屏的调度类,相当于锁屏的大脑,控制着整个锁屏. KeyguardService:负责锁屏模块 ...

最新文章

  1. mysql 新增更新_MySQL新增数据,存在就更新,不存在就添加(转帖加实测)
  2. HDU 6015 Colorful Tree(2017多校)
  3. 【Linux 内核 内存管理】内存管理架构 ⑤ ( sbrk 内存分配系统调用代码示例 | 在 /proc/pid/maps 中查看进程堆内存详情 )
  4. 疫情下的硅谷区块链创业者
  5. 验证手机号码归属地_手机号码归属地能否取消? 工信部回复了
  6. 移动设备input输入框点击后自动选中内容_带你用 Python 实现自动化群控(入门篇)...
  7. JVM调优大全及实战总结
  8. yum用法及程序编译安装
  9. 人脸方向学习(三):人脸质量评价-人脸模糊检测总结二
  10. chrome提示安装unity web player
  11. 惠普薄锐ENVY 15 X360升级DIY
  12. SVN 版本回退 命令行
  13. 建立完善的员工晋升机制_员工晋升管理制度精选5篇
  14. 恒生电子软件工程师面试
  15. 新西兰计算机最好大学排名,2017新西兰大学计算机专业排名TOP10经典院校一览
  16. 计算机在化学中论文3000字,化学论文范文3000字_化学论文发表
  17. file:/usr/local/hive/iotmp/89de7dfe-8f26-4a6e-87b4-bacd16c2b2c8/hive_2021-11-05_05-06-07_555_3392062
  18. 诺禾-实验技巧之WB篇
  19. 视频教程-深度学习与PyTorch入门实战教程-深度学习
  20. 高德地图api实现导航功能(使用经验)避坑关注

热门文章

  1. ubuntu-桌面版-常用设置
  2. InvokeHelper,让跨线程访问/修改主界面控件不再麻烦(转)
  3. 有趣的MS Live Labs
  4. Cross_validation.train_test_split 中 stratify这个参数的意义是什么?
  5. Git 学习笔记:自定义Git(完)
  6. NVIDIA cuda7在centos6.5中的安装
  7. 【笔记】Comparison of Object Detection and Patch-Based Classification Deep Learning Models on Mid- to La
  8. Caffe学习笔记3——制作并训练自己的数据集
  9. 云炬Android开发笔记 3-1项目架构初始化
  10. 踩内存是什么意思啊_Win10任务管理器中的quot;共享GPU内存quot;是什么意思?