一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

淺析android鎖屏開(kāi)機(jī)繪制流程(基于android4.0源碼分析)

 昵稱11482448 2013-09-04

    

      最近大體看了一下android源碼鎖屏模塊,順便把自己的收獲在此記錄下來(lái),希望對(duì)研究鎖屏的同行們有所幫助(對(duì)于鎖屏模塊,本人也沒(méi)什么時(shí)間去真正的深究,只是摸清了個(gè)大概,若有奇異和錯(cuò)誤之處,懇請(qǐng)指出)

    好了,廢話不多說(shuō)了。

     Android源碼模塊鎖屏大體分為兩種:

    1.LockScreen: 系統(tǒng)默認(rèn)的鎖屏,就是我們所常見(jiàn)的系統(tǒng)原生波紋解鎖(涉及MultiWaveView視圖類)。如下圖:

       

 

    2.UnlockScreen: 進(jìn)入手機(jī)的設(shè)置----->安全----->屏幕鎖定。在列表中將看到的可選擇項(xiàng):圖案,PIN,密碼等鎖屏都?xì)w為UnlockScreen。(可選擇任意一項(xiàng)切換鎖屏)

 

    鎖屏相關(guān)源碼所在路徑:

    1.鎖屏模塊的框架源碼所在路徑為:frameworks\base\policy\src\com\android\internal\policy\impl(本文所涉及的代碼都在這個(gè)目錄里)

    2.相關(guān)的鎖屏自定義View類及與其關(guān)聯(lián)類的源碼所在路徑為:frameworks\base\core\java\com\android\internal\widget

 

     開(kāi)機(jī)繪制鎖屏流程代碼分析:

      手機(jī)開(kāi)機(jī)時(shí),在SystemServer類的init2()方法中會(huì)啟動(dòng)線程類ServerThread的run方法如下

     

  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>  

  ------>上述代碼中的wm為WindowManagerService的引用,所以,wm.systemReady()為調(diào)用WindowManagerService的systemReady()方法,如下代碼:

  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. }  

 ------>WindowManagerPolicy的實(shí)現(xiàn)類為PhoneWindowManager,所以,接著調(diào)用到PhoneWindowManager的systemReady,如下:

  1. public class PhoneWindowManager implements WindowManagerPolicy   
  2. {  
  3.    KeyguardViewMediator mKeyguardMediator;  
  4.   ...  
  5.    //手機(jī)開(kāi)機(jī)后執(zhí)行  
  6.     public void systemReady() {  
  7.         // tell the keyguard  
  8.         mKeyguardMediator.onSystemReady(); //進(jìn)行待機(jī)鎖屏及解鎖邏輯  
  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. }  

------>接著,調(diào)用到KeyguardViewMediator類的onSystemReady()方法如下:

  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.     //開(kāi)機(jī)顯示鎖屏入口  
  9.     public void onSystemReady() {  
  10.         synchronized (this) {  
  11.             if (DEBUG) Log.d(TAG, "onSystemReady");  
  12.             mSystemReady = true;  
  13.             doKeyguardLocked();  
  14.         }  
  15.     }  
  16.   ...  
  17. }  

------>調(diào)用KeyguardViewMediator.doKeyguardLocked方法,在該方法中,先執(zhí)行一些條件判斷,若滿足直接返回。若不直接返回,則緊接著調(diào)用KeyguardViewMediator. showLocked方法,代碼如下: 

  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(); //確保屏幕處于喚醒狀態(tài)  
  10.         Message msg = mHandler.obtainMessage(SHOW);  
  11.         mHandler.sendMessage(msg);  
  12.     }  
  13.   ...  

----->通過(guò)handler發(fā)送消息SHOW到handleMessage處理,如下:

  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對(duì)象 , 異步處理  
  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. ...  

------>當(dāng)case SHOW:時(shí),調(diào)用 handleShow方法,如下:

  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.   ...  

----->接著調(diào)用KeyguardViewManager的show方法。KeyguardViewManager.show()中,會(huì)對(duì)KeyguardViewHost(mKeyguardHost)和LockPatternKeyguardView(mKeyguardView)是否為空進(jìn)行判斷:

  1).若KeyguardViewHost為空,則創(chuàng)建KeyguardViewHost,同時(shí)設(shè)置更新其相關(guān)的布局參數(shù)。然后將KeyguardViewHost對(duì)象添加到WindowManagerImpl中。

  2). 若LockPatternKeyguardView為空,創(chuàng)建LockPatternKeyguardView對(duì)象,通過(guò)調(diào)用LockPatternKeyguardViewProperties.createKeyguardView()創(chuàng)建。同時(shí)為它設(shè)置回調(diào)。然后將創(chuàng)建得到的對(duì)象添加到KeyguardViewHost。

   代碼如下:

  1. public class KeyguardViewManager implements KeyguardWindowController {  
  2.   ...  
  3. private FrameLayout mKeyguardHost;  //該ViewGroup作為頂層View,作為WindowManager添加至窗口   
  4. private KeyguardViewBase mKeyguardView; //具體窗口內(nèi)容。   
  5. //以上兩種的關(guān)系相當(dāng)于DecorView和我們Activity內(nèi)設(shè)置的資源文件一樣   
  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.             //創(chuàng)建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.             /*創(chuàng)建鎖屏視圖,即創(chuàng)建一個(gè)LockPatternKeyguardView對(duì)象(FrameLayout)。在創(chuàng)建LockPatternKeyguardView 
  68.              * 對(duì)象的同時(shí),其構(gòu)造方法中會(huì)調(diào)用getInitialMode()得到初始化的狀態(tài)Mode(Lock or unLock) 
  69.              */  
  70.             mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);  
  71.             mKeyguardView.setId(R.id.lock_screen);  
  72.             //設(shè)置回調(diào)  
  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.                 //調(diào)用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. }  

------>在上面的代碼中,當(dāng)KeyguardViewHost為空時(shí),首先會(huì)調(diào)用KeyguardViewProperties的實(shí)現(xiàn)類LockPatternKeyguardViewProperties的createKeyguardView方法,來(lái)構(gòu)造一個(gè)LockPatternKeyguardView對(duì)象,如下:

  1. <span style="font-size:14px;">public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {  
  2.   ...  
  3. //創(chuàng)建一個(gè)LockPatternKeyguardView對(duì)象   
  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>  

------->而在LockPatternKeyguardView的構(gòu)造函數(shù)中,有如下調(diào)用(以下的流程代碼實(shí)現(xiàn)均在LockPatternKeyguardView中處理):

  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. }  

----->getInitialMode()得到當(dāng)前鎖屏模式(lock or unlock),代碼如下:

  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.   //得到初始化的狀態(tài)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. ...  

----->再回到updateScreen(getInitialMode(), false),該函數(shù)的實(shí)現(xiàn)如下:

  1. ...  
  2. /根據(jù)參數(shù)(Lock/unLock),判斷顯示為L(zhǎng)ockScreen或者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.             //重構(gòu)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的具體解鎖項(xiàng),如密碼鎖(Password)或pin鎖;枚舉類UnlockMode定義了幾種不同的Unlock解鎖;  
  22.           final UnlockMode unlockMode = getUnlockMode();   
  23.           if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {  
  24.             //重構(gòu)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. ...  

------>updateScreen(getInitialMode(), false)中,對(duì)傳進(jìn)來(lái)的參數(shù)Mode進(jìn)行對(duì)等判斷:

  1). 若為L(zhǎng)ockScreen模式鎖屏,則如下:

  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.                 //重構(gòu)LockScreen  
  5.                 recreateLockScreen();  
  6.             }  
  7.         }</span>  

----->然后調(diào)用到LockPatternKeyguardView.recreateLockScreen(),在該函數(shù)中,首先會(huì)對(duì)LockScreen進(jìn)行判斷,若之前已存在該對(duì)象,則進(jìn)行移除。然后接著再重新調(diào)用createLockScreen()構(gòu)建LockScreen對(duì)象。然后將該對(duì)象添加到LockPatternKeyguardView中。createLockScreen()的代碼如下:

  1. ...  
  2. 創(chuàng)建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. ...  

  2).若為UnlockScreen模式鎖屏,則如下:

  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的具體解鎖項(xiàng),如密碼鎖(Password)或pin鎖;枚舉類UnlockMode定義了幾種不同的Unlock解鎖;  
  5.             final UnlockMode unlockMode = getUnlockMode();   
  6.             if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {  
  7.                 //重構(gòu)unLock解鎖  
  8.                 recreateUnlockScreen(unlockMode);  
  9.             }  
  10.         }  

----->然后調(diào)用到LockPatternKeyguardView.recreateUnlockScreen(unlockMode),在該函數(shù)中,進(jìn)行的處理和recreateLockScreen函數(shù)中的處理原則基本上一致。則調(diào)用createUnlockScreen(unlockMode)時(shí),會(huì)根據(jù)unlockMode的不同創(chuàng)建相應(yīng)的UnlockScreen具體解鎖項(xiàng)。                   

     recreateUnlockScreen如下代碼:

  1. ...  
  2. 重新構(gòu)建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添進(jìn)LockPatternKeyguardView  
  14.       addView(mUnlockScreen);  
  15.   }  
  16. ...  

----->接著調(diào)用createUnlockScreenFor方法,在該方法中會(huì)根據(jù)傳進(jìn)來(lái)的參數(shù)UnlockMode(定義UnlockScreen可選項(xiàng)的枚舉類)判斷,來(lái)決定創(chuàng)建啟用對(duì)應(yīng)的UnlockScreen,代碼實(shí)現(xiàn)如下:

  1. ...  
  2. 根據(jù)不同的Unlock Mode , 創(chuàng)建不同的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.         //啟動(dòng)圖案解鎖(手機(jī)設(shè)置中可見(jiàn)切換)  
  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.         //啟動(dòng)PIN解鎖(手機(jī)設(shè)置中可見(jiàn)切換)  
  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.         //啟動(dòng)密碼解鎖(手機(jī)設(shè)置中可見(jiàn)切換)  
  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. ...  

在此,LockScreen或者UnlockScreen就創(chuàng)建出來(lái)了,當(dāng)然,只是創(chuàng)建了相應(yīng)對(duì)象,還得再顯示。

------>再次回到KeyguardViewManager類的show方法,在執(zhí)行完該方法中的的mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this)代碼流程后,接著執(zhí)行mKeyguardView.show(),即調(diào)用KeyguardViewBase的實(shí)現(xiàn)類LockPatternKeyguardView的show方法,如下:

  1. //該類作為L(zhǎng)ockScreen和UnLockScreen界面的載體,控制顯示哪個(gè)界面  
  2. public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback,  
  3.         KeyguardUpdateMonitor.InfoCallback {    
  4. ...  
  5. @Override  
  6.     public void show() {  
  7.         /*判斷鎖屏模式(當(dāng)然,調(diào)用該方法之前已經(jīng)創(chuàng)建LockPatternKeyguardView對(duì)象, 
  8.          * 即已調(diào)用getInitialMode()獲得了Mode),根據(jù)結(jié)果顯示鎖屏。 
  9.          */  
  10.         if (mMode == Mode.LockScreen) {   
  11.             //調(diào)用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(); //顯示人臉解鎖區(qū)域  
  24.         } else {  
  25.             hideFaceLockArea(); //隱藏人臉解鎖區(qū)域  
  26.         }  
  27.     }  
  28.   ...  
  29. }  

這樣,LockScreen或者UnlockScreen就顯示出來(lái)了,我們?cè)賮?lái)看看LockScreen的onResume()方法的實(shí)現(xiàn),代碼如下:

  1. //手機(jī)默認(rèn)的解鎖實(shí)現(xiàn)類  
  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. }  

   對(duì)于LockScreen或者UnlockScreen的界面布局和View等可視化UI界面時(shí)如何畫(huà)出來(lái)的,具體可參考LockScreen類的實(shí)現(xiàn),UnlockScreen可參考的類:PatternUnlockScreen、SimPukUnlockScreen、SimUnlockScreen、AccountUnlockScreen、PasswordUnlockScreen。有興趣的讀者可自行去研究。

 

小結(jié):

    這篇文章只是講解手機(jī)開(kāi)機(jī)啟動(dòng)時(shí),繪制鎖屏的流程,至于通過(guò)power鍵點(diǎn)亮,點(diǎn)暗鎖屏,解鎖,鎖屏,LockScreen或者UnlockScreen的UI界面可視化的實(shí)現(xiàn)等等的分析,有時(shí)間再去深究。

    但,萬(wàn)變不離其宗,鎖屏的核心類在于KeyguardViewMediator,該類提供了一些接口,由PhoneWindowManager去訪問(wèn)控制Keyguard,而它的初始化是在PhoneWindowManager的init()函數(shù)中創(chuàng)建的。也就是在我們上面分析的代碼中,在執(zhí)行mPolicy.systemReady()時(shí)(由PhoneWindowManage調(diào)用r),已經(jīng)創(chuàng)建了KeyguardViewMediator。所以,分析好該類是很重要的。

         OK,個(gè)人對(duì)鎖屏開(kāi)機(jī)繪制流程的粗略分析就到這里了,春節(jié)即將來(lái)臨,在此祝愿所有身處挨踢行業(yè)的同志們,回家過(guò)個(gè)好年?。?/span>

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    字幕日本欧美一区二区| 97精品人妻一区二区三区麻豆| 欧美胖熟妇一区二区三区| 一二区不卡不卡在线观看| 午夜福利92在线观看| 91日韩欧美中文字幕| 冬爱琴音一区二区中文字幕| 2019年国产最新视频| 四季av一区二区播放| 欧美丰满大屁股一区二区三区 | 男女午夜福利院在线观看| 亚洲国产色婷婷久久精品| 最近中文字幕高清中文字幕无| 91免费一区二区三区| 91久久精品国产成人| 欧美一本在线免费观看| 日本一本在线免费福利| 中文字幕一区久久综合| 在线观看免费无遮挡大尺度视频| 国产精品第一香蕉视频| 丰满人妻一二区二区三区av| 国产白丝粉嫩av在线免费观看| 在线播放欧美精品一区| 91精品国产品国语在线不卡| 国产又粗又长又大高潮视频| 免费观看一级欧美大片| 国产专区亚洲专区久久| 极品熟女一区二区三区| 美女被啪的视频在线观看| 国产成人精品国内自产拍| 午夜福利视频偷拍91| 久久福利视频这里有精品| 日本东京热加勒比一区二区| 国产精品香蕉在线的人| 99热九九热这里只有精品| 熟女中文字幕一区二区三区| 亚洲欧美日韩国产自拍| 国产日韩欧美在线播放| 91精品视频免费播放| 国产精品免费不卡视频| 国产精品丝袜一二三区|