国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android4.0開發(fā)之Keyguard解鎖屏機制詳解

2019-12-12 01:22:54
字體:
供稿:網(wǎng)友

本文實例講述了Android4.0 Keyguard解鎖屏機制。分享給大家供大家參考,具體如下:

Keyguard解鎖屏是Android系統(tǒng)中必不可少的模塊,用戶在開機后或者在點擊Power按鈕屏幕變亮后首先看到的畫面即為解鎖屏模塊對應的界面。Keyguard模塊功能相對簡單:

第一:直觀地顯示手機當前的關(guān)鍵信息:比如電池信息、運營商信息、日期信息以及通話短信信息等。

第二:增強手機的安全性能:為了安全,用戶可以在Setting里的Secure選項中設(shè)置password、pattern、account等不同的安全策略,防止非法用戶訪問手機系統(tǒng)。

但從代碼實現(xiàn)的角度該模塊邏輯還是比較復雜,不但需要監(jiān)聽系統(tǒng)中的多種event,比如sim、電話、電池以及Carrier等狀態(tài),還要正確反映、顯示屏幕的不同狀態(tài)。為了對Keyguard模塊的處理邏輯有更清晰的理解,下面首先從系統(tǒng)構(gòu)成的角度概括介紹Keyguard解鎖屏模塊的框架,然后對解鎖屏模塊中重要的處理邏輯進行詳細介紹。

一、系統(tǒng)介紹

Keyguard解鎖屏模塊的框架類圖如下:

圖中僅列出了Keyguard解鎖屏模塊涉及的重要類,這些類實現(xiàn)了Keyguard模塊的主要功能,它們的作用如下:

PhoneWindowManager是解鎖屏模塊對外交互的接口,窗口管理Service、電源管理Service等外部模塊都是通過PhoneWindowManager訪問Keyguard內(nèi)部功能。
KeyguardViewMediator類為解鎖屏模塊的中介者,以中介的身份處理keyguard狀態(tài)變化,處理event、power管理、PhoneWindowManager通知等請求,并作為回調(diào)對象供解鎖屏模塊的其它類回調(diào)。
KeyguardUpdateMonitor類為解鎖屏模塊的監(jiān)聽者,它負責監(jiān)聽時間、sim卡、運營商信息、電池信息、電話信息等狀態(tài)的變化,并通知keyguard View模塊更新顯示。
KeyguardViewManager類為解鎖屏view模塊的管理者,管理解鎖屏界面的創(chuàng)建、顯示、隱藏以及重置等。
LockPatternKeyguardView類為解鎖屏模塊的View界面,為所有解鎖屏界面的host view。根據(jù)設(shè)置的安全策略,顯示不同的解鎖屏界面。Google原生代碼中實現(xiàn)了6種解鎖屏界面:

1) LockScreen:用于顯示屏幕加鎖狀態(tài)
2) PatternUnlockScreen:實現(xiàn)圖案解鎖模式
3) SimPukUnlockScreen:屏幕實現(xiàn)SIM PUK碼解鎖模式
4) SimUnlockScreen:實現(xiàn)Sim PIN碼解鎖模式
5) AccountUnlockScreen:實現(xiàn) GOOGLE 帳戶解鎖
6) PasswordUnlockScreen:實現(xiàn)自定義密碼解鎖模式

二、主要邏輯

1、Keyguard模塊啟動、顯示邏輯

即手機開機進入系統(tǒng)到鎖屏界面顯示的過程。手機系統(tǒng)啟動過程中會自動啟動Keyguard解鎖屏模塊,該模塊的創(chuàng)建始于WindowManagerService類,時序圖如下:

1)WindowManagerService在啟動時會實例化PhoneWindowManager對象mPolicy,并在窗口管理Policy線程PolicyThread中初始化,代碼如下:

public void run() { Looper.prepare(); WindowManagerPolicyThread.set(this, Looper.myLooper()); ...... mPolicy.init(mContext, mService, mService, mPM); ...... Looper.loop();}

從代碼中可以看到PhoneWindowManager在獨立的線程和Looper消息隊列中處理Message事件,該Looper對象也為解鎖屏模塊使用以處理所有handler消息。
2)mPolicy函數(shù)init中創(chuàng)建解鎖屏模塊的中介者――KeyguardViewMediator對象。
3)在KeyguardViewMediator的構(gòu)造函數(shù)中創(chuàng)建LockPatternKeyguardViewProperties、KeyguardUpdateMonitor、KeyguardViewManager等重要對象:

public KeyguardViewMediator(Context context, PhoneWindowManager callback,   LocalPowerManager powerManager) {  ……  mUpdateMonitor = new KeyguardUpdateMonitor(context);  mUpdateMonitor.registerInfoCallback(this);  mUpdateMonitor.registerSimStateCallback(this);  mLockPatternUtils = new LockPatternUtils(mContext);  mKeyguardViewProperties= new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);  mKeyguardViewManager = new KeyguardViewManager(    context, WindowManagerImpl.getDefault(), this,    mKeyguardViewProperties, mUpdateMonitor);  …… }

KeyguardViewMediator中記錄了PhoneWindowManager、PowerManager等對象,同時也保存了LockPatternKeyguardViewProperties、KeyguardUpdateMonitor、KeyguardViewManager等模塊內(nèi)的重要對象,這樣該類以中介者身份在Keyguard模塊對外交互以及內(nèi)部各對象間的交互中發(fā)揮了重要作用。

4)KeyguardUpdateMonitor構(gòu)造函數(shù)中創(chuàng)建mHandler,用以響應處理該類監(jiān)聽的各事件狀態(tài)的改變,并在handle處理函數(shù)中通知mInfoCallbacks和mSimStateCallbacks保存的監(jiān)聽對象,監(jiān)聽事件有ACTION_TIME_TICK、ACTION_TIME_CHANGED、ACTION_BATTERY_CHANGED、ACTION_TIMEZONE_CHANGED、ACTION_SIM_STATE_CHANGED、        ACTION_PHONE_STATE_CHANGED、RINGER_MODE_CHANGED_ACTION

至此Keyguard解鎖屏模塊中重要的類對象已經(jīng)實例化,但是還未涉及解鎖屏View界面的創(chuàng)建和顯示。

5)系統(tǒng)啟動后解鎖屏界面的首次顯示始于WindowManagerService的systemReady函數(shù),通知PhoneWindowManager系統(tǒng)就緒,代碼如下:

public void systemReady() { mPolicy.systemReady();}

6)PhoneWindowManager的systemReady函數(shù)中通知解鎖屏模塊的中介者KeyguardViewMediator對象系統(tǒng)就緒

7)中介者KeyguardViewMediator類中處理系統(tǒng)就緒情形:調(diào)用doKeyguardLocked函數(shù)顯示解鎖屏界面:

public void onSystemReady() { synchronized (this) {   mSystemReady = true;   doKeyguardLocked(); }}private void doKeyguardLocked() {  ......  // if the keyguard is already showing, don't bother  if (mKeyguardViewManager.isShowing()) {   if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");   return;  }  .....  if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");  showLocked();}

showLocked函數(shù)中發(fā)送SHOW消息異步處理解鎖屏界面顯示的請求。

8)handleShow中處理界面顯示的消息請求,函數(shù)中調(diào)用KeyguardViewManager的函數(shù)show實現(xiàn)解鎖屏界面的真正顯示:

public synchronized void show() {  ......  if (mKeyguardHost == null) {   if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");   mKeyguardHost = new KeyguardViewHost(mContext, mCallback);   ......   mViewManager.addView(mKeyguardHost, lp);  }  ......  mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);  if (mKeyguardView == null) {   mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);   ......   mKeyguardHost.addView(mKeyguardView, lp);   ......  }  ......}

該函數(shù)中主要創(chuàng)建了Keyguard顯示View中的兩個重要的對象:mKeyguardHost和mKeyguardView,它們都是繼承于FrameLayout,為解鎖屏視圖的根view。

9)在創(chuàng)建對象mKeyguardView時根據(jù)解鎖屏mode創(chuàng)建解鎖屏界面:

protected void updateScreen(Mode mode, boolean force) {   ......  // Re-create the lock screen if necessary  if (mode == Mode.LockScreen || mShowLockBeforeUnlock) {   if (force || mLockScreen == null) {    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) {   final UnlockMode unlockMode = getUnlockMode();   if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {    recreateUnlockScreen(unlockMode);   }  }  ......}

10)在函數(shù)createLockScreen或者createUnlockScreenFor中創(chuàng)建具體的Lock或者Unlock View界面,并調(diào)用show函數(shù)進行顯示

至此,Keyguard解鎖屏模塊從系統(tǒng)開機啟動到界面顯示的處理邏輯已介紹完成。

2、兩次按下Power按鈕屏幕亮->暗->亮過程中鎖屏模塊處理邏輯

連續(xù)兩次按下Power按鈕屏幕亮->暗->亮過程中解鎖屏模塊處理邏輯的時序圖如下:

1)在函數(shù)PowerManagerService:setPowerState中響應Power按鈕的按下,代碼如下:

private void setPowerState(int newState, boolean noChangeLights, int reason){  synchronized (mLocks) {   ……   if (oldScreenOn != newScreenOn) {    if (newScreenOn) {     // When the user presses the power button, we need to always send out the     // notification that it's going to sleep so the keyguard goes on. But     // we can't do that until the screen fades out, so we don't show the keyguard     // too early.     if (mStillNeedSleepNotification) {      sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);     }     ……     if (err == 0) {      sendNotificationLocked(true, -1);      // Update the lights *after* taking care of turning the      // screen on, so we do this after our notifications are      // enqueued and thus will delay turning on the screen light      // until the windows are correctly displayed.      if (stateChanged) {       updateLightsLocked(newState, 0);      }      mPowerState |= SCREEN_ON_BIT;     }    } else {     ……     if (!mScreenBrightness.animating) {      err = screenOffFinishedAnimatingLocked(reason);     }     ……    }   }   ……  }}

根據(jù)上面的代碼邏輯,屏幕即將變暗時調(diào)用函數(shù)screenOffFinishedAnimatingLocked,屏幕即將變亮時調(diào)用函數(shù)sendNotificationLocked。

2)函數(shù)sendNotificationLocked發(fā)送Notification Task線程到handler,并異步執(zhí)行通知解鎖屏模塊進行狀態(tài)更新:

private Runnable mNotificationTask = new Runnable(){  public void run()  {   while (true) {    ......    if (value == 1) {     policy.screenTurningOn(mScreenOnListener);     ......    }    else if (value == 0) {     policy.screenTurnedOff(why);     ......    }    else {     // If we're in this case, then this handler is running for a previous     // paired transaction. mBroadcastWakeLock will already have been released.     break;    }   }  }};

上面的線程函數(shù)run中分別處理了屏幕變暗和變亮的情形。按下Power按鈕屏幕變暗時調(diào)用了函數(shù)screenTurnedOff,why為變暗的原因,此處值為OFF_BECAUSE_OF_USER。

3)KeyguardViewMediator中根據(jù)屏幕變暗的原因分別處理屏幕變暗事件:

/*** Called to let us know the screen was turned off.* @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},* {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or* {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.*/public void onScreenTurnedOff(int why) { synchronized (this) { …… else if (mShowing) { //若是(mShowing)則重置顯示界面,否則重新顯示鎖屏界面    notifyScreenOffLocked();    resetStateLocked();   } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) {    // if the screen turned off because of timeout, set an alarm    // to enable it a little bit later (i.e, give the user a chance    // to turn the screen back on within a certain window without    // having to unlock the screen)    ……    if (timeout <= 0) {     // Lock now     mSuppressNextLockSound = true;     doKeyguardLocked();    } else {     // Lock in the future     long when = SystemClock.elapsedRealtime() + timeout;     Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);     intent.putExtra("seq", mDelayedShowingSequence);     PendingIntent sender = PendingIntent.getBroadcast(mContext,       0, intent, PendingIntent.FLAG_CANCEL_CURRENT);     mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,       sender);    }   } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {    // Do not enable the keyguard if the prox sensor forced the screen off.   } else { //顯示鎖屏屏幕    doKeyguardLocked();   }  }}

4)調(diào)用doKeyguardLocked重新顯示鎖屏界面,隨后的鎖屏界面顯示邏輯與Keyguard模塊啟動顯示中的8~10步相同,不再贅述。

5)按下Power按鈕屏幕即將由暗->亮時代碼處理邏輯重新執(zhí)行1~2步,第二步中屏幕變亮時調(diào)用的函數(shù)是PhoneWindowManager:screenTurningOn。

6)函數(shù)screenTurningOn中調(diào)用中介者KeyguardViewMediator的函數(shù)onScreenTurnedOn,該函數(shù)直接調(diào)用屏幕變亮異步通知函數(shù)KeyguardViewMediator:notifyScreenOnLocked,告知解鎖屏模塊屏幕即將變亮。

7)函數(shù)handleNotifyScreenOn響應屏幕變亮的通知

8)程序執(zhí)行到LockPatternKeyguardView:onScreenTurnedOn函數(shù),并調(diào)用show函數(shù)進行解鎖屏界面的顯示,代碼如下:

public void show() {  if (mMode == Mode.LockScreen) {   ((KeyguardScreen) mLockScreen).onResume();  } else {   ((KeyguardScreen) mUnlockScreen).onResume();  }  ...... }

至此,邏輯處理完成。

3、自定義口令解鎖邏輯

自定義口令解鎖始于PasswordUnlockScreen,時序圖如下:

1)解鎖屏界面輸入密碼點擊確定按鈕后,在函數(shù)onEditorAction中進行響應:

public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {  // Check if this was the result of hitting the enter key  if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE    || actionId == EditorInfo.IME_ACTION_NEXT) {   verifyPasswordAndUnlock();   return true;  }  return false;}

2)在函數(shù)verifyPasswordAndUnlock中對輸入的密碼進行判斷,如果輸入正確,測調(diào)用keyguardDone響應解鎖完成的操作。mCallback.keyguardDone(true)調(diào)用是所有解鎖屏mode情形在解鎖成功后必須調(diào)用的函數(shù),隨后的處理邏輯對于不同的解鎖屏界面也是相同的。

3)回調(diào)KeyguardScreenCallback和KeyguardViewMediator的函數(shù)keyguardDone,在后者的keyguardDone函數(shù)中,異步發(fā)送keyDone事件:

public void keyguardDone(boolean authenticated, boolean wakeup) { synchronized (this) {  ……  Message msg = mHandler.obtainMessage(KEYGUARD_DONE);  msg.arg1 = wakeup ? 1 : 0;  mHandler.sendMessage(msg);  …… }}

4)函數(shù)KeyguardViewMediator:handleKeyguardDone異步處理keyguardDone事件,調(diào)用handleHide隱藏鎖屏界面。

5)KeyguardViewManager.hide函數(shù)中調(diào)用鎖屏界面的銷毀函LockPatternKeyguardView:cleanUp數(shù)隱藏銷毀界面,如下:

public void cleanUp() { if (mLockScreen != null) {  ((KeyguardScreen) mLockScreen).onPause();  ((KeyguardScreen) mLockScreen).cleanUp();  this.removeView(mLockScreen);  mLockScreen = null; } if (mUnlockScreen != null) {  ((KeyguardScreen) mUnlockScreen).onPause();  ((KeyguardScreen) mUnlockScreen).cleanUp();  this.removeView(mUnlockScreen);  mUnlockScreen = null; } ......}

至此,解鎖完成。

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進階教程》、《Android視圖View技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android操作SQLite數(shù)據(jù)庫技巧總結(jié)》、《Android操作json格式數(shù)據(jù)技巧總結(jié)》、《Android資源操作技巧匯總》及《Android控件用法總結(jié)

希望本文所述對大家Android程序設(shè)計有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 永兴县| 新乡县| 唐河县| 城固县| 米脂县| 蒲江县| 清水河县| 蓝田县| 山西省| 名山县| 改则县| 新乐市| 彰武县| 久治县| 石渠县| 襄樊市| 师宗县| 肇庆市| 荣昌县| 芜湖县| 靖边县| 陈巴尔虎旗| 收藏| 鹿邑县| 昭通市| 西宁市| 宜兰市| 通州区| 昔阳县| 桂平市| 五指山市| 丁青县| 平度市| 西盟| 南漳县| 曲水县| 扶风县| 东兰县| 东山县| 通州市| 锡林浩特市|