浅析android锁屏开机绘制流程(基于android4.0源码分析) .

最近大体看了一下android源码锁屏模块,顺便把自己的收获在此记录下来,希望对研究锁屏的同行们有所帮助(对于锁屏模块,本人也没什么时间去真正的深究,只是摸清了个大概,若有奇异和错误之处,恳请指出)

    好了,废话不多说了。

     Android源码模块锁屏大体分为两种:

    1.LockScreen: 系统默认的锁屏,就是我们所常见的系统原生波纹解锁(涉及MultiWaveView视图类)。如下图:

        

 

    2.UnlockScreen: 进入手机的设置----->安全----->屏幕锁定。在列表中将看到的可选择项:图案,PIN,密码等锁屏都归为UnlockScreen。(可选择任意一项切换锁屏)

 

    锁屏相关源码所在路径:

    1.锁屏模块的框架源码所在路径为:frameworks\base\policy\src\com\android\internal\policy\impl(本文所涉及的代码都在这个目录里)

    2.相关的锁屏自定义View类及与其关联类的源码所在路径为:frameworks\base\core\java\com\android\internal\widget

 

     开机绘制锁屏流程代码分析:

      手机开机时,在SystemServer类的init2()方法中会启动线程类ServerThread的run方法如下

     

[java]   view plain copy print ?
  1. class ServerThread extends Thread  
  2.  {  
  3.   
  4.      @Override  
  5.       public void run()   
  6.       {  
  7.           WindowManagerService wm = null;  
  8.            ...  
  9.         try  
  10.            {  
  11.               wm.systemReady();  
  12.            } catch (Throwable e)  
  13.            {  
  14.                reportWtf("making Window Manager Service ready", e);  
  15.             }  
  16.            ...  
  17.        }  
  18.   }  
  19.   
  20.   <SPAN style="FONT-SIZE: 14px">   </SPAN>  
class ServerThread extends Thread
{
 
     @Override
      public void run()
      {
          WindowManagerService wm = null;
           ...
        try
           {
              wm.systemReady();
           } catch (Throwable e)
           {
               reportWtf("making Window Manager Service ready", e);
            }
           ...
       }
  }
 
 
  

  ------>上述代码中的wm为WindowManagerService的引用,所以,wm.systemReady()为调用WindowManagerService的systemReady()方法,如下代码:

[java]   view plain copy print ?
  1. public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs   
  2. {  
  3.   final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();  
  4.   ...  
  5.   public void systemReady() {  
  6.        mPolicy.systemReady();  
  7.    }  
  8.   ...  
  9. }  
public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs
{
  final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
  ...
  public void systemReady() {
       mPolicy.systemReady();
   }
  ...
}
 

 ------>WindowManagerPolicy的实现类为PhoneWindowManager,所以,接着调用到PhoneWindowManager的systemReady,如下:

[java]   view plain copy print ?
  1. public class PhoneWindowManager implements WindowManagerPolicy   
  2. {  
  3.    KeyguardViewMediator mKeyguardMediator;  
  4.   ...  
  5.    //手机开机后执行   
  6.     public void systemReady() {  
  7.         // tell the keyguard   
  8.         mKeyguardMediator.onSystemReady(); //进行待机锁屏及解锁逻辑   
  9.         android.os.SystemProperties.set("dev.bootcomplete""1");   
  10.         synchronized (mLock) {  
  11.             updateOrientationListenerLp();  
  12.             mSystemReady = true;  
  13.             mHandler.post(new Runnable() {  
  14.                 public void run() {  
  15.                     updateSettings();  
  16.                 }  
  17.             });  
  18.         }  
  19.     }  
  20.   ...  
  21. }  
public class PhoneWindowManager implements WindowManagerPolicy
{
   KeyguardViewMediator mKeyguardMediator;
  ...
   //手机开机后执行
    public void systemReady() {
        // tell the keyguard
        mKeyguardMediator.onSystemReady(); //进行待机锁屏及解锁逻辑
        android.os.SystemProperties.set("dev.bootcomplete", "1");
        synchronized (mLock) {
            updateOrientationListenerLp();
            mSystemReady = true;
            mHandler.post(new Runnable() {
                public void run() {
                    updateSettings();
                }
            });
        }
    }
  ...
}

------>接着,调用到KeyguardViewMediator类的onSystemReady()方法如下:

[java]   view plain copy print ?
  1. public class KeyguardViewMediator implements KeyguardViewCallback,  
  2.         KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback   
  3. {  
  4.   ...  
  5.    /** 
  6.      * Let us know that the system is ready after startup. 
  7.      */  
  8.     //开机显示锁屏入口   
  9.     public void onSystemReady() {  
  10.         synchronized (this) {  
  11.             if (DEBUG) Log.d(TAG, "onSystemReady");  
  12.             mSystemReady = true;  
  13.             doKeyguardLocked();  
  14.         }  
  15.     }  
  16.   ...  
  17. }  
public class KeyguardViewMediator implements KeyguardViewCallback,
        KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback
{
  ...
   /**
     * Let us know that the system is ready after startup.
     */
    //开机显示锁屏入口
    public void onSystemReady() {
        synchronized (this) {
            if (DEBUG) Log.d(TAG, "onSystemReady");
            mSystemReady = true;
            doKeyguardLocked();
        }
    }
  ...
}

------>调用KeyguardViewMediator.doKeyguardLocked方法,在该方法中,先执行一些条件判断,若满足直接返回。若不直接返回,则紧接着调用KeyguardViewMediator. showLocked方法,代码如下: 

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

----->通过handler发送消息SHOW到handleMessage处理,如下:

[java]   view plain copy print ?
  1. ...  
  2. *  
  3.    * This handler will be associated with the policy thread, which will also  
  4.    * be the UI thread of the keyguard.  Since the apis of the policy, and therefore  
  5.    * this class, can be called by other threads, any action that directly  
  6.    * interacts with the keyguard ui should be posted to this handler, rather  
  7.    * than called directly.  
  8.    */  
  9.   //Handler对象 , 异步处理   
  10.   private Handler mHandler = new Handler() {  
  11.       @Override  
  12.       public void handleMessage(Message msg) { //异步处理    
  13.           switch (msg.what) {  
  14.               case TIMEOUT:  
  15.                   handleTimeout(msg.arg1);  
  16.                   return ;  
  17.               case SHOW:  
  18.                   handleShow();  
  19.                   return ;  
  20.               case HIDE:  
  21.                   handleHide();  
  22.                   return ;  
  23.               case RESET:  
  24.                   handleReset();  
  25.                   return ;  
  26.               case VERIFY_UNLOCK:  
  27.                   handleVerifyUnlock();  
  28.                   return;  
  29.               case NOTIFY_SCREEN_OFF:  
  30.                   handleNotifyScreenOff();  
  31.                   return;  
  32.               case NOTIFY_SCREEN_ON:  
  33.                   handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);  
  34.                   return;  
  35.               case WAKE_WHEN_READY:  
  36.                   handleWakeWhenReady(msg.arg1);  
  37.                   return;  
  38.               case KEYGUARD_DONE:  
  39.                   handleKeyguardDone(msg.arg1 != 0);  
  40.                   return;  
  41.               case KEYGUARD_DONE_DRAWING:  
  42.                   handleKeyguardDoneDrawing();  
  43.                   return;  
  44.               case KEYGUARD_DONE_AUTHENTICATING:  
  45.                   keyguardDone(true);  
  46.                   return;  
  47.               case SET_HIDDEN:  
  48.                   handleSetHidden(msg.arg1 != 0);  
  49.                   break;  
  50.               case KEYGUARD_TIMEOUT:  
  51.                   synchronized (KeyguardViewMediator.this) {  
  52.                       doKeyguardLocked();  
  53.                   }  
  54.                   break;  
  55.           }  
  56.       }  
  57.   };  
  58. ...  
  ...
/**
     * This handler will be associated with the policy thread, which will also
     * be the UI thread of the keyguard.  Since the apis of the policy, and therefore
     * this class, can be called by other threads, any action that directly
     * interacts with the keyguard ui should be posted to this handler, rather
     * than called directly.
     */
    //Handler对象 , 异步处理
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) { //异步处理
            switch (msg.what) {
                case TIMEOUT:
                    handleTimeout(msg.arg1);
                    return ;
                case SHOW:
                    handleShow();
                    return ;
                case HIDE:
                    handleHide();
                    return ;
                case RESET:
                    handleReset();
                    return ;
                case VERIFY_UNLOCK:
                    handleVerifyUnlock();
                    return;
                case NOTIFY_SCREEN_OFF:
                    handleNotifyScreenOff();
                    return;
                case NOTIFY_SCREEN_ON:
                    handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);
                    return;
                case WAKE_WHEN_READY:
                    handleWakeWhenReady(msg.arg1);
                    return;
                case KEYGUARD_DONE:
                    handleKeyguardDone(msg.arg1 != 0);
                    return;
                case KEYGUARD_DONE_DRAWING:
                    handleKeyguardDoneDrawing();
                    return;
                case KEYGUARD_DONE_AUTHENTICATING:
                    keyguardDone(true);
                    return;
                case SET_HIDDEN:
                    handleSetHidden(msg.arg1 != 0);
                    break;
                case KEYGUARD_TIMEOUT:
                    synchronized (KeyguardViewMediator.this) {
                        doKeyguardLocked();
                    }
                    break;
            }
        }
    };
  ...

------>当case SHOW:时,调用 handleShow方法,如下:

[java]   view plain copy print ?
  1. private KeyguardViewManager mKeyguardViewManager;  
  2.   ...  
  3. /** 
  4.      * Handle message sent by {@link #showLocked}. 
  5.      * @see #SHOW 
  6.      */  
  7.     //显示锁屏界面   
  8.     private void handleShow() {  
  9.         synchronized (KeyguardViewMediator.this) {  
  10.             if (DEBUG) Log.d(TAG, "handleShow");  
  11.             if (!mSystemReady) return;  
  12.   
  13.             mKeyguardViewManager.show();  
  14.             mShowing = true;  
  15.             adjustUserActivityLocked();  
  16.             adjustStatusBarLocked();  
  17.             try {  
  18.                 ActivityManagerNative.getDefault().closeSystemDialogs("lock");  
  19.             } catch (RemoteException e) {  
  20.             }  
  21.   
  22.             // Do this at the end to not slow down display of the keyguard.   
  23.             playSounds(true);  
  24.   
  25.             mShowKeyguardWakeLock.release();  
  26.         }  
  27.     }  
  28.   ...  
private KeyguardViewManager mKeyguardViewManager;
  ...
/**
     * Handle message sent by {@link #showLocked}.
     * @see #SHOW
     */
    //显示锁屏界面
    private void handleShow() {
        synchronized (KeyguardViewMediator.this) {
            if (DEBUG) Log.d(TAG, "handleShow");
            if (!mSystemReady) return;
 
            mKeyguardViewManager.show();
            mShowing = true;
            adjustUserActivityLocked();
            adjustStatusBarLocked();
            try {
                ActivityManagerNative.getDefault().closeSystemDialogs("lock");
            } catch (RemoteException e) {
            }
 
            // Do this at the end to not slow down display of the keyguard.
            playSounds(true);
 
            mShowKeyguardWakeLock.release();
        }
    }
  ...

----->接着调用KeyguardViewManager的show方法。KeyguardViewManager.show()中,会对KeyguardViewHost(mKeyguardHost)和LockPatternKeyguardView(mKeyguardView)是否为空进行判断:

  1).若KeyguardViewHost为空,则创建KeyguardViewHost,同时设置更新其相关的布局参数。然后将KeyguardViewHost对象添加到WindowManagerImpl中。

  2). 若LockPatternKeyguardView为空,创建LockPatternKeyguardView对象,通过调用LockPatternKeyguardViewProperties.createKeyguardView()创建。同时为它设置回调。然后将创建得到的对象添加到KeyguardViewHost。

   代码如下:

[java]   view plain copy print ?
  1. public class KeyguardViewManager implements KeyguardWindowController {  
  2.   ...  
  3. private FrameLayout mKeyguardHost;  //该ViewGroup作为顶层View,作为WindowManager添加至窗口    
  4. private KeyguardViewBase mKeyguardView; //具体窗口内容。    
  5. //以上两种的关系相当于DecorView和我们Activity内设置的资源文件一样    
  6. private final KeyguardViewProperties mKeyguardViewProperties;  
  7.   ...  
  8. /** 
  9.      * Show the keyguard.  Will handle creating and attaching to the view manager 
  10.      * lazily. 
  11.      */  
  12.     //显示锁屏界面   
  13.     public synchronized void show() {  
  14.         if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);  
  15.   
  16.         Resources res = mContext.getResources();  
  17.         boolean enableScreenRotation =  
  18.                 SystemProperties.getBoolean("lockscreen.rot_override",false)  
  19.                 || res.getBoolean(R.bool.config_enableLockScreenRotation);  
  20.         if (mKeyguardHost == null) {  
  21.             if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");  
  22.             //创建KeyguardViewHost(FrameLayout)   
  23.             mKeyguardHost = new KeyguardViewHost(mContext, mCallback);  
  24.   
  25.             final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;  
  26.             int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN  
  27.                     | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER  
  28.                     | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING  
  29.                     /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 
  30.                     | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;  
  31.             if (!mNeedsInput) {  
  32.                 flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;  
  33.             }  
  34.             if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(  
  35.                     Context.WINDOW_SERVICE)).getDefaultDisplay())) {  
  36.                 flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;  
  37.             }  
  38.             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(  
  39.                     stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,  
  40.                     flags, PixelFormat.TRANSLUCENT);  
  41.             lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;  
  42.             lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;  
  43.             if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(  
  44.                     Context.WINDOW_SERVICE)).getDefaultDisplay())) {  
  45.                 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;  
  46.                 lp.privateFlags |=  
  47.                         WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;  
  48.             }  
  49.             lp.setTitle("Keyguard");  
  50.             mWindowLayoutParams = lp;  
  51.             //添加KeyguardViewHost   
  52.             mViewManager.addView(mKeyguardHost, lp);  
  53.         }  
  54.   
  55.         if (enableScreenRotation) {  
  56.             if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");  
  57.             mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;  
  58.         } else {  
  59.             if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");  
  60.             mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;  
  61.         }  
  62.         //刷新布局   
  63.         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);  
  64.   
  65.         if (mKeyguardView == null) {  
  66.             if (DEBUG) Log.d(TAG, "keyguard view is null, creating it...");  
  67.             /*创建锁屏视图,即创建一个LockPatternKeyguardView对象(FrameLayout)。在创建LockPatternKeyguardView 
  68.              * 对象的同时,其构造方法中会调用getInitialMode()得到初始化的状态Mode(Lock or unLock) 
  69.              */  
  70.             mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);  
  71.             mKeyguardView.setId(R.id.lock_screen);  
  72.             //设置回调   
  73.             mKeyguardView.setCallback(mCallback);  
  74.   
  75.             final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(  
  76.                     ViewGroup.LayoutParams.MATCH_PARENT,  
  77.                     ViewGroup.LayoutParams.MATCH_PARENT);  
  78.   
  79.             //将视图加入根布局mKeyguardHost(FrameLayout)   
  80.             mKeyguardHost.addView(mKeyguardView, lp);  
  81.   
  82.             if (mScreenOn) {  
  83.                 //调用LockPatternKeyguardView的show   
  84.                 mKeyguardView.show();  
  85.             }  
  86.         }  
  87.   
  88.         // Disable aspects of the system/status/navigation bars that are not appropriate or   
  89.         // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.   
  90.         // Other disabled bits are handled by the KeyguardViewMediator talking directly to the  
  91.         // status bar service.   
  92.         int visFlags =  
  93.                 ( View.STATUS_BAR_DISABLE_BACK  
  94.                 | View.STATUS_BAR_DISABLE_HOME  
  95.                 );  
  96.         mKeyguardHost.setSystemUiVisibility(visFlags);  
  97.   
  98.         mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);  
  99.         mKeyguardHost.setVisibility(View.VISIBLE);  
  100.         mKeyguardView.requestFocus();  
  101.     }  
  102.   ...  
  103. }  
public class KeyguardViewManager implements KeyguardWindowController {
  ...
private FrameLayout mKeyguardHost;  //该ViewGroup作为顶层View,作为WindowManager添加至窗口
private KeyguardViewBase mKeyguardView; //具体窗口内容。
//以上两种的关系相当于DecorView和我们Activity内设置的资源文件一样
private final KeyguardViewProperties mKeyguardViewProperties;
  ...
/**
     * Show the keyguard.  Will handle creating and attaching to the view manager
     * lazily.
     */
    //显示锁屏界面
    public synchronized void show() {
        if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
 
        Resources res = mContext.getResources();
        boolean enableScreenRotation =
                SystemProperties.getBoolean("lockscreen.rot_override",false)
                || res.getBoolean(R.bool.config_enableLockScreenRotation);
        if (mKeyguardHost == null) {
            if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
            //创建KeyguardViewHost(FrameLayout)
            mKeyguardHost = new KeyguardViewHost(mContext, mCallback);
 
            final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
            int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
                    | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
                    /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
            if (!mNeedsInput) {
                flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
            }
            if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(
                    Context.WINDOW_SERVICE)).getDefaultDisplay())) {
                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
            }
            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
                    flags, PixelFormat.TRANSLUCENT);
            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
            lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
            if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(
                    Context.WINDOW_SERVICE)).getDefaultDisplay())) {
                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
                lp.privateFlags |=
                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
            }
            lp.setTitle("Keyguard");
            mWindowLayoutParams = lp;
            //添加KeyguardViewHost
            mViewManager.addView(mKeyguardHost, lp);
        }
 
        if (enableScreenRotation) {
            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");
            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
        } else {
            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");
            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
        }
        //刷新布局
        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
 
        if (mKeyguardView == null) {
            if (DEBUG) Log.d(TAG, "keyguard view is null, creating it...");
            /*创建锁屏视图,即创建一个LockPatternKeyguardView对象(FrameLayout)。在创建LockPatternKeyguardView
             * 对象的同时,其构造方法中会调用getInitialMode()得到初始化的状态Mode(Lock or unLock)
             */
            mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);
            mKeyguardView.setId(R.id.lock_screen);
            //设置回调
            mKeyguardView.setCallback(mCallback);
 
            final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
 
            //将视图加入根布局mKeyguardHost(FrameLayout)
            mKeyguardHost.addView(mKeyguardView, lp);
 
            if (mScreenOn) {
                //调用LockPatternKeyguardView的show
                mKeyguardView.show();
            }
        }
 
        // Disable aspects of the system/status/navigation bars that are not appropriate or
        // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.
        // Other disabled bits are handled by the KeyguardViewMediator talking directly to the
        // status bar service.
        int visFlags =
                ( View.STATUS_BAR_DISABLE_BACK
                | View.STATUS_BAR_DISABLE_HOME
                );
        mKeyguardHost.setSystemUiVisibility(visFlags);
 
        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
        mKeyguardHost.setVisibility(View.VISIBLE);
        mKeyguardView.requestFocus();
    }
  ...
}

------>在上面的代码中,当KeyguardViewHost为空时,首先会调用KeyguardViewProperties的实现类LockPatternKeyguardViewProperties的createKeyguardView方法,来构造一个LockPatternKeyguardView对象,如下:

[java]   view plain copy print ?
  1. <SPAN style="FONT-SIZE: 14px">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.     }  
  10.   ...  
  11. }</SPAN>  
public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {
  ...
//创建一个LockPatternKeyguardView对象
    public KeyguardViewBase createKeyguardView(Context context,
            KeyguardUpdateMonitor updateMonitor,
            KeyguardWindowController controller) {
        return new LockPatternKeyguardView(context, updateMonitor,
                mLockPatternUtils, controller);
    }
  ...
}

------->而在LockPatternKeyguardView的构造函数中,有如下调用(以下的流程代码实现均在LockPatternKeyguardView中处理):

[java]   view plain copy print ?
  1. /** 
  2.      * @param context Used to inflate, and create views. 
  3.      * @param updateMonitor Knows the state of the world, and passed along to each 
  4.      *   screen so they can use the knowledge, and also register for callbacks 
  5.      *   on dynamic information. 
  6.      * @param lockPatternUtils Used to look up state of lock pattern. 
  7.      */  
  8.     public LockPatternKeyguardView(  
  9.             Context context,  
  10.             KeyguardUpdateMonitor updateMonitor,  
  11.             LockPatternUtils lockPatternUtils,  
  12.             KeyguardWindowController controller) {  
  13.   ...  
  14.   updateScreen(getInitialMode(), false);  
  15.   ...  
  16.   
  17. }  
/**
     * @param context Used to inflate, and create views.
     * @param updateMonitor Knows the state of the world, and passed along to each
     *   screen so they can use the knowledge, and also register for callbacks
     *   on dynamic information.
     * @param lockPatternUtils Used to look up state of lock pattern.
     */
    public LockPatternKeyguardView(
            Context context,
            KeyguardUpdateMonitor updateMonitor,
            LockPatternUtils lockPatternUtils,
            KeyguardWindowController controller) {
  ...
  updateScreen(getInitialMode(), false);
  ...
 
}

----->getInitialMode()得到当前锁屏模式(lock or unlock),代码如下:

[java]   view plain copy print ?
  1. ...  
  2. *  
  3.    * Given the current state of things, what should be the initial mode of  
  4.    * the lock screen (lock or unlock).  
  5.    */  
  6.   //得到初始化的状态Mode (lock or unlock).   
  7.   private Mode getInitialMode() {  
  8.       final IccCard.State simState = mUpdateMonitor.getSimState();  
  9.       if (stuckOnLockScreenBecauseSimMissing() ||  
  10.               (simState == IccCard.State.PUK_REQUIRED &&  
  11.                       !mLockPatternUtils.isPukUnlockScreenEnable())) {  
  12.           return Mode.LockScreen;  
  13.       } else {  
  14.           if (!isSecure() || mShowLockBeforeUnlock) {  
  15.               return Mode.LockScreen;  
  16.           } else {  
  17.               return Mode.UnlockScreen;  
  18.           }  
  19.       }  
  20.   }  
  21. ...  
  ...
/**
     * Given the current state of things, what should be the initial mode of
     * the lock screen (lock or unlock).
     */
    //得到初始化的状态Mode (lock or unlock).
    private Mode getInitialMode() {
        final IccCard.State simState = mUpdateMonitor.getSimState();
        if (stuckOnLockScreenBecauseSimMissing() ||
                (simState == IccCard.State.PUK_REQUIRED &&
                        !mLockPatternUtils.isPukUnlockScreenEnable())) {
            return Mode.LockScreen;
        } else {
            if (!isSecure() || mShowLockBeforeUnlock) {
                return Mode.LockScreen;
            } else {
                return Mode.UnlockScreen;
            }
        }
    }
  ...

----->再回到updateScreen(getInitialMode(), false),该函数的实现如下:

[java]   view plain copy print ?
  1. ...  
  2. /根据参数(Lock/unLock),判断显示为LockScreen或者UnlockScreen界面  
  3.   private void updateScreen(Mode mode, boolean force) {  
  4.   
  5.       if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode  
  6.               + " last mode=" + mMode + ", force = " + force, new RuntimeException());  
  7.   
  8.       mMode = mode;  
  9.   
  10.       // Re-create the lock screen if necessary   
  11.       if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {  
  12.           if (force || mLockScreen == null) {  
  13.             //重构LockScreen   
  14.               recreateLockScreen();  
  15.           }  
  16.       }  
  17.   
  18.       // Re-create the unlock screen if necessary. This is primarily required to properly handle   
  19.       // SIM state changes. This typically happens when this method is called by reset()   
  20.       if (mode == Mode.UnlockScreen) {  
  21.         //获取UnlockScreen的具体解锁项,如密码锁(Password)或pin锁;枚举类UnlockMode定义了几种不同的Unlock解锁;   
  22.           final UnlockMode unlockMode = getUnlockMode();   
  23.           if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {  
  24.             //重构unLock解锁   
  25.               recreateUnlockScreen(unlockMode);  
  26.           }  
  27.       }  
  28.   
  29.       // visibleScreen should never be null   
  30.       final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;  
  31.       final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;  
  32.   
  33.       // do this before changing visibility so focus isn't requested before the input   
  34.       // flag is set   
  35.       mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());  
  36.   
  37.       if (DEBUG_CONFIGURATION) {  
  38.           Log.v(TAG, "Gone=" + goneScreen);  
  39.           Log.v(TAG, "Visible=" + visibleScreen);  
  40.       }  
  41.   
  42.       if (mScreenOn) {  
  43.           if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {  
  44.               ((KeyguardScreen) goneScreen).onPause(); //隐藏被切换掉的锁(Lock or unLock)   
  45.           }  
  46.           if (visibleScreen.getVisibility() != View.VISIBLE) {  
  47.               ((KeyguardScreen) visibleScreen).onResume();//显示切换得到的锁(Lock or unLock)  
  48.           }  
  49.       }  
  50.   
  51.       if (goneScreen != null) {  
  52.           goneScreen.setVisibility(View.GONE);  
  53.       }  
  54.       visibleScreen.setVisibility(View.VISIBLE);  
  55.       requestLayout();  
  56.   
  57.       if (!visibleScreen.requestFocus()) {  
  58.           throw new IllegalStateException("keyguard screen must be able to take "  
  59.                   + "focus when shown " + visibleScreen.getClass().getCanonicalName());  
  60.       }  
  61.   }  
  62. ...  
  ...
//根据参数(Lock/unLock),判断显示为LockScreen或者UnlockScreen界面
    private void updateScreen(Mode mode, boolean force) {
 
        if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode
                + " last mode=" + mMode + ", force = " + force, new RuntimeException());
 
        mMode = mode;
 
        // Re-create the lock screen if necessary
        if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {
            if (force || mLockScreen == null) {
                //重构LockScreen
                recreateLockScreen();
            }
        }
 
        // Re-create the unlock screen if necessary. This is primarily required to properly handle
        // SIM state changes. This typically happens when this method is called by reset()
        if (mode == Mode.UnlockScreen) {
            //获取UnlockScreen的具体解锁项,如密码锁(Password)或pin锁;枚举类UnlockMode定义了几种不同的Unlock解锁;
            final UnlockMode unlockMode = getUnlockMode();
            if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
                //重构unLock解锁
                recreateUnlockScreen(unlockMode);
            }
        }
 
        // visibleScreen should never be null
        final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen;
        final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen;
 
        // do this before changing visibility so focus isn't requested before the input
        // flag is set
        mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());
 
        if (DEBUG_CONFIGURATION) {
            Log.v(TAG, "Gone=" + goneScreen);
            Log.v(TAG, "Visible=" + visibleScreen);
        }
 
        if (mScreenOn) {
            if (goneScreen != null && goneScreen.getVisibility() == View.VISIBLE) {
                ((KeyguardScreen) goneScreen).onPause(); //隐藏被切换掉的锁(Lock or unLock)
            }
            if (visibleScreen.getVisibility() != View.VISIBLE) {
                ((KeyguardScreen) visibleScreen).onResume();//显示切换得到的锁(Lock or unLock)
            }
        }
 
        if (goneScreen != null) {
            goneScreen.setVisibility(View.GONE);
        }
        visibleScreen.setVisibility(View.VISIBLE);
        requestLayout();
 
        if (!visibleScreen.requestFocus()) {
            throw new IllegalStateException("keyguard screen must be able to take "
                    + "focus when shown " + visibleScreen.getClass().getCanonicalName());
        }
    }
  ...

------>在updateScreen(getInitialMode(), false)中,对传进来的参数Mode进行对等判断:

  1). 若为LockScreen模式锁屏,则如下:

[java]   view plain copy print ?
  1. <SPAN style="FONT-FAMILY: Comic Sans MS; FONT-SIZE: 18px">// Re-create the lock screen if necessary   
  2.         if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {  
  3.             if (force || mLockScreen == null) {  
  4.                 //重构LockScreen   
  5.                 recreateLockScreen();  
  6.             }  
  7.         }</SPAN>  
// Re-create the lock screen if necessary
        if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {
            if (force || mLockScreen == null) {
                //重构LockScreen
                recreateLockScreen();
            }
        }

----->然后调用到LockPatternKeyguardView.recreateLockScreen(),在该函数中,首先会对LockScreen进行判断,若之前已存在该对象,则进行移除。然后接着再重新调用createLockScreen()构建LockScreen对象。然后将该对象添加到LockPatternKeyguardView中。createLockScreen()的代码如下:

[java]   view plain copy print ?
  1. ...  
  2. 创建lockScreen     
  3.   View createLockScreen() {  
  4.       View lockView = new LockScreen(  
  5.               mContext,  
  6.               mConfiguration,  
  7.               mLockPatternUtils,  
  8.               mUpdateMonitor,  
  9.               mKeyguardScreenCallback);  
  10.       initializeTransportControlView(lockView);  
  11.       return lockView;  
  12.   }  
  13. ...  
  ...
//创建lockScreen  
    View createLockScreen() {
        View lockView = new LockScreen(
                mContext,
                mConfiguration,
                mLockPatternUtils,
                mUpdateMonitor,
                mKeyguardScreenCallback);
        initializeTransportControlView(lockView);
        return lockView;
    }
  ...

  2).若为UnlockScreen模式锁屏,则如下:

[java]   view plain copy print ?
  1. // Re-create the unlock screen if necessary. This is primarily required to properly handle   
  2.         // SIM state changes. This typically happens when this method is called by reset()   
  3.         if (mode == Mode.UnlockScreen) {  
  4.             //获取UnlockScreen的具体解锁项,如密码锁(Password)或pin锁;枚举类UnlockMode定义了几种不同的Unlock解锁;   
  5.             final UnlockMode unlockMode = getUnlockMode();   
  6.             if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {  
  7.                 //重构unLock解锁   
  8.                 recreateUnlockScreen(unlockMode);  
  9.             }  
  10.         }  
// Re-create the unlock screen if necessary. This is primarily required to properly handle
        // SIM state changes. This typically happens when this method is called by reset()
        if (mode == Mode.UnlockScreen) {
            //获取UnlockScreen的具体解锁项,如密码锁(Password)或pin锁;枚举类UnlockMode定义了几种不同的Unlock解锁;
            final UnlockMode unlockMode = getUnlockMode();
            if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
                //重构unLock解锁
                recreateUnlockScreen(unlockMode);
            }
        }

----->然后调用到LockPatternKeyguardView.recreateUnlockScreen(unlockMode),在该函数中,进行的处理和recreateLockScreen函数中的处理原则基本上一致。则调用createUnlockScreen(unlockMode)时,会根据unlockMode的不同创建相应的UnlockScreen具体解锁项。                   

     recreateUnlockScreen如下代码:

[java]   view plain copy print ?
  1. ...  
  2. 重新构建UnlockScreen     
  3.   private void recreateUnlockScreen(UnlockMode unlockMode) {  
  4.       if (mUnlockScreen != null) {  
  5.           ((KeyguardScreen) mUnlockScreen).onPause();  
  6.           ((KeyguardScreen) mUnlockScreen).cleanUp();  
  7.           //mUnlockScreen不为空,则移除UnlockScreen   
  8.           removeView(mUnlockScreen);  
  9.       }  
  10.   
  11.       mUnlockScreen = createUnlockScreenFor(unlockMode);  
  12.       mUnlockScreen.setVisibility(View.INVISIBLE);  
  13.       //将UnlockScreen添进LockPatternKeyguardView   
  14.       addView(mUnlockScreen);  
  15.   }  
  16. ...  
  ...
//重新构建UnlockScreen  
    private void recreateUnlockScreen(UnlockMode unlockMode) {
        if (mUnlockScreen != null) {
            ((KeyguardScreen) mUnlockScreen).onPause();
            ((KeyguardScreen) mUnlockScreen).cleanUp();
            //mUnlockScreen不为空,则移除UnlockScreen
            removeView(mUnlockScreen);
        }
 
        mUnlockScreen = createUnlockScreenFor(unlockMode);
        mUnlockScreen.setVisibility(View.INVISIBLE);
        //将UnlockScreen添进LockPatternKeyguardView
        addView(mUnlockScreen);
    }
  ...

----->接着调用createUnlockScreenFor方法,在该方法中会根据传进来的参数UnlockMode(定义UnlockScreen可选项的枚举类)判断,来决定创建启用对应的UnlockScreen,代码实现如下:

[java]   view plain copy print ?
  1. ...  
  2. 根据不同的Unlock Mode , 创建不同的UnlockScreen     
  3.   View createUnlockScreenFor(UnlockMode unlockMode) {  
  4.       View unlockView = null;  
  5.   
  6.       if (DEBUG) Log.d(TAG,  
  7.               "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);  
  8.   
  9.       if (unlockMode == UnlockMode.Pattern) {  
  10.         //启动图案解锁(手机设置中可见切换)   
  11.           PatternUnlockScreen view = new PatternUnlockScreen(  
  12.                   mContext,  
  13.                   mConfiguration,  
  14.                   mLockPatternUtils,  
  15.                   mUpdateMonitor,  
  16.                   mKeyguardScreenCallback,  
  17.                   mUpdateMonitor.getFailedAttempts());  
  18.           view.setEnableFallback(mEnableFallback);  
  19.           unlockView = view;  
  20.       } else if (unlockMode == UnlockMode.SimPuk) {  
  21.           unlockView = new SimPukUnlockScreen(  
  22.                   mContext,  
  23.                   mConfiguration,  
  24.                   mUpdateMonitor,  
  25.                   mKeyguardScreenCallback,  
  26.                   mLockPatternUtils);  
  27.       } else if (unlockMode == UnlockMode.SimPin) {  
  28.         //启动PIN解锁(手机设置中可见切换)   
  29.           unlockView = new SimUnlockScreen(  
  30.                   mContext,  
  31.                   mConfiguration,  
  32.                   mUpdateMonitor,  
  33.                   mKeyguardScreenCallback,  
  34.                   mLockPatternUtils);  
  35.       } else if (unlockMode == UnlockMode.Account) {  
  36.           try {  
  37.               unlockView = new AccountUnlockScreen(  
  38.                       mContext,  
  39.                       mConfiguration,  
  40.                       mUpdateMonitor,  
  41.                       mKeyguardScreenCallback,  
  42.                       mLockPatternUtils);  
  43.           } catch (IllegalStateException e) {  
  44.               Log.i(TAG, "Couldn't instantiate AccountUnlockScreen"  
  45.                     + " (IAccountsService isn't available)");  
  46.               // TODO: Need a more general way to provide a   
  47.               // platform-specific fallback UI here.   
  48.               // For now, if we can't display the account login   
  49.               // unlock UI, just bring back the regular "Pattern" unlock mode.   
  50.   
  51.               // (We do this by simply returning a regular UnlockScreen   
  52.               // here.  This means that the user will still see the   
  53.               // regular pattern unlock UI, regardless of the value of   
  54.               // mUnlockScreenMode or whether or not we're in the   
  55.               // "permanently locked" state.)   
  56.               return createUnlockScreenFor(UnlockMode.Pattern);  
  57.           }  
  58.       } else if (unlockMode == UnlockMode.Password) {  
  59.         //启动密码解锁(手机设置中可见切换)   
  60.           unlockView = new PasswordUnlockScreen(  
  61.                   mContext,  
  62.                   mConfiguration,  
  63.                   mLockPatternUtils,  
  64.                   mUpdateMonitor,  
  65.                   mKeyguardScreenCallback);  
  66.       } else {  
  67.           throw new IllegalArgumentException("unknown unlock mode " + unlockMode);  
  68.       }  
  69.       initializeTransportControlView(unlockView);  
  70.       initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled   
  71.   
  72.       mUnlockScreenMode = unlockMode;  
  73.       return unlockView;  
  74.   }  
  75. ...  
  ...
//根据不同的Unlock Mode , 创建不同的UnlockScreen  
    View createUnlockScreenFor(UnlockMode unlockMode) {
        View unlockView = null;
 
        if (DEBUG) Log.d(TAG,
                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);
 
        if (unlockMode == UnlockMode.Pattern) {
            //启动图案解锁(手机设置中可见切换)
            PatternUnlockScreen view = new PatternUnlockScreen(
                    mContext,
                    mConfiguration,
                    mLockPatternUtils,
                    mUpdateMonitor,
                    mKeyguardScreenCallback,
                    mUpdateMonitor.getFailedAttempts());
            view.setEnableFallback(mEnableFallback);
            unlockView = view;
        } else if (unlockMode == UnlockMode.SimPuk) {
            unlockView = new SimPukUnlockScreen(
                    mContext,
                    mConfiguration,
                    mUpdateMonitor,
                    mKeyguardScreenCallback,
                    mLockPatternUtils);
        } else if (unlockMode == UnlockMode.SimPin) {
            //启动PIN解锁(手机设置中可见切换)
            unlockView = new SimUnlockScreen(
                    mContext,
                    mConfiguration,
                    mUpdateMonitor,
                    mKeyguardScreenCallback,
                    mLockPatternUtils);
        } else if (unlockMode == UnlockMode.Account) {
            try {
                unlockView = new AccountUnlockScreen(
                        mContext,
                        mConfiguration,
                        mUpdateMonitor,
                        mKeyguardScreenCallback,
                        mLockPatternUtils);
            } catch (IllegalStateException e) {
                Log.i(TAG, "Couldn't instantiate AccountUnlockScreen"
                      + " (IAccountsService isn't available)");
                // TODO: Need a more general way to provide a
                // platform-specific fallback UI here.
                // For now, if we can't display the account login
                // unlock UI, just bring back the regular "Pattern" unlock mode.
 
                // (We do this by simply returning a regular UnlockScreen
                // here.  This means that the user will still see the
                // regular pattern unlock UI, regardless of the value of
                // mUnlockScreenMode or whether or not we're in the
                // "permanently locked" state.)
                return createUnlockScreenFor(UnlockMode.Pattern);
            }
        } else if (unlockMode == UnlockMode.Password) {
            //启动密码解锁(手机设置中可见切换)
            unlockView = new PasswordUnlockScreen(
                    mContext,
                    mConfiguration,
                    mLockPatternUtils,
                    mUpdateMonitor,
                    mKeyguardScreenCallback);
        } else {
            throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
        }
        initializeTransportControlView(unlockView);
        initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled
 
        mUnlockScreenMode = unlockMode;
        return unlockView;
    }
  ...

在此,LockScreen或者UnlockScreen就创建出来了,当然,只是创建了相应对象,还得再显示。

------>再次回到KeyguardViewManager类的show方法,在执行完该方法中的的mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this)代码流程后,接着执行mKeyguardView.show(),即调用KeyguardViewBase的实现类LockPatternKeyguardView的show方法,如下:

[java]   view plain copy print ?
  1. //该类作为LockScreen和UnLockScreen界面的载体,控制显示哪个界面   
  2. public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback,  
  3.         KeyguardUpdateMonitor.InfoCallback {    
  4. ...  
  5. @Override  
  6.     public void show() {  
  7.         /*判断锁屏模式(当然,调用该方法之前已经创建LockPatternKeyguardView对象, 
  8.          * 即已调用getInitialMode()获得了Mode),根据结果显示锁屏。 
  9.          */  
  10.         if (mMode == Mode.LockScreen) {   
  11.             //调用onResume显示锁屏   
  12.             ((KeyguardScreen) mLockScreen).onResume();  
  13.         } else {  
  14.             ((KeyguardScreen) mUnlockScreen).onResume();  
  15.         }  
  16.   
  17.         if (mLockPatternUtils.usingBiometricWeak() &&  
  18.             mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {  
  19.             // Note that show() gets called before the screen turns off to set it up for next time  
  20.             // it is turned on.  We don't want to set a timeout on the FaceLock area here because it  
  21.             // may be gone by the time the screen is turned on again.  We set the timout when the  
  22.             // screen turns on instead.   
  23.             showFaceLockArea(); //显示人脸解锁区域   
  24.         } else {  
  25.             hideFaceLockArea(); //隐藏人脸解锁区域   
  26.         }  
  27.     }  
  28.   ...  
  29. }  
//该类作为LockScreen和UnLockScreen界面的载体,控制显示哪个界面
public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback,
        KeyguardUpdateMonitor.InfoCallback { 
...
@Override
    public void show() {
        /*判断锁屏模式(当然,调用该方法之前已经创建LockPatternKeyguardView对象,
         * 即已调用getInitialMode()获得了Mode),根据结果显示锁屏。
         */
        if (mMode == Mode.LockScreen) {
            //调用onResume显示锁屏
            ((KeyguardScreen) mLockScreen).onResume();
        } else {
            ((KeyguardScreen) mUnlockScreen).onResume();
        }
 
        if (mLockPatternUtils.usingBiometricWeak() &&
            mLockPatternUtils.isBiometricWeakInstalled() && !mHasOverlay) {
            // Note that show() gets called before the screen turns off to set it up for next time
            // it is turned on.  We don't want to set a timeout on the FaceLock area here because it
            // may be gone by the time the screen is turned on again.  We set the timout when the
            // screen turns on instead.
            showFaceLockArea(); //显示人脸解锁区域
        } else {
            hideFaceLockArea(); //隐藏人脸解锁区域
        }
    }
  ...
}

这样,LockScreen或者UnlockScreen就显示出来了,我们再来看看LockScreen的onResume()方法的实现,代码如下:

[java]   view plain copy print ?
  1. //手机默认的解锁实现类   
  2. class LockScreen extends LinearLayout implements KeyguardScreen {  
  3.   ...  
  4. //处理LockScreen的显示   
  5. public void onResume() {  
  6.         mStatusViewManager.onResume();  
  7.          postDelayed(mOnResumePing, ON_RESUME_PING_DELAY);  
  8.     }  
  9.   ...  
  10. }  
//手机默认的解锁实现类
class LockScreen extends LinearLayout implements KeyguardScreen {
  ...
//处理LockScreen的显示
public void onResume() {
        mStatusViewManager.onResume();
         postDelayed(mOnResumePing, ON_RESUME_PING_DELAY);
    }
  ...
}

   对于LockScreen或者UnlockScreen的界面布局和View等可视化UI界面时如何画出来的,具体可参考LockScreen类的实现,UnlockScreen可参考的类:PatternUnlockScreen、SimPukUnlockScreen、SimUnlockScreen、AccountUnlockScreen、PasswordUnlockScreen。有兴趣的读者可自行去研究。

 

小结:

    这篇文章只是讲解手机开机启动时,绘制锁屏的流程,至于通过power键点亮,点暗锁屏,解锁,锁屏,LockScreen或者UnlockScreen的UI界面可视化的实现等等的分析,有时间再去深究。

    但,万变不离其宗,锁屏的核心类在于KeyguardViewMediator,该类提供了一些接口,由PhoneWindowManager去访问控制Keyguard,而它的初始化是在PhoneWindowManager的init()函数中创建的。也就是在我们上面分析的代码中,在执行mPolicy.systemReady()时(由PhoneWindowManage调用r),已经创建了KeyguardViewMediator。所以,分析好该类是很重要的。

         OK,个人对锁屏开机绘制流程的粗略分析就到这里了,春节即将来临,在此祝愿所有身处挨踢行业的同志们,回家过个好年!!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值