1. 程式人生 > >Android關機流程原始碼分析

Android關機流程原始碼分析

上一篇文章Android 開關機動畫顯示原始碼分析詳細介紹了開關機動畫的顯示過程,Android系統開機時,在啟動SurfaceFlinger服務過程中通過Android屬性系統方式來啟動bootanim程序,實現開機動畫顯示過程;當系統關機時,又是如何啟動關機動畫的呢?Android系統的整個關機流程又是怎樣的呢?本文就針對這兩個問題透過原始碼來給出具體的分析。我們知道,當長按電源鍵,系統會彈出關機提示對話方塊


當點選選擇關機時,系統就會完成整個關機流程。接下來就通過原始碼來介紹Android關機流程的完整實現過程。當長按電源鍵時,按鍵訊息被分發到PhoneWindowManager的interceptKeyBeforeQueueing函式中處理:

  1. publicint interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {  
  2.     ...  
  3.     switch (keyCode) {  
  4.         ...  
  5.         case KeyEvent.KEYCODE_POWER: {  
  6.             result &= ~ACTION_PASS_TO_USER;  
  7.             if (down) {  
  8.                 if (isScreenOn && !mPowerKeyTriggered  
  9.                         && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {  
  10.                     mPowerKeyTriggered = true;  
  11.                     mPowerKeyTime = event.getDownTime();  
  12.                     interceptScreenshotChord();//抓屏
  13.                 }  
  14.                 ITelephony telephonyService = getTelephonyService();  
  15.                 boolean hungUp = false;  
  16.                 if (telephonyService != null) {  
  17.                     try {  
  18.                         if (telephonyService.isRinging()) {  
  19.                             //當來電時按下電源鍵,啟動靜音
  20.                             telephonyService.silenceRinger();  
  21.                         } elseif ((mIncallPowerBehavior  
  22.                                 & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
  23.                                 && telephonyService.isOffhook()) {  
  24.                             // Otherwise, if "Power button ends call" is enabled,
  25.                             // the Power button will hang up any current active call.
  26.                             hungUp = telephonyService.endCall();  
  27.                         }  
  28.                     } catch (RemoteException ex) {  
  29.                         Log.w(TAG, "ITelephony threw RemoteException", ex);  
  30.                     }  
  31.                 }  
  32.                 interceptPowerKeyDown(!isScreenOn || hungUp  
  33.                         || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);  
  34.             } else {  
  35.                 ...  
  36.             }  
  37.             break;  
  38.         }  
  39.         ...  
  40.     }  
  41.     return result;  
  42. }  
電源鍵和音量鍵的組合可以實現特定功能,比如按下電源鍵和音量向下鍵,可實現抓屏,interceptKeyBeforeQueueing函式首先根據條件處理電源鍵按下的特定任務,然後呼叫interceptPowerKeyDown做進一步處理
  1. privatevoid interceptPowerKeyDown(boolean handled) {  
  2.     mPowerKeyHandled = handled;  
  3.     if (!handled) {  
  4.         //隔500ms處理電源按鍵事件
  5.         mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());  
  6.     }  
  7. }  
這裡的mHandler是在初始化PhoneWindowManager物件時建立的
  1. publicvoid init(Context context, IWindowManager windowManager,WindowManagerFuncs windowManagerFuncs,  
  2.         LocalPowerManager powerManager) {  
  3.     ...  
  4.     mHandler = new PolicyHandler();  
  5.     ...  
  6. }  
將一個Runnable物件mPowerLongPress傳送到PolicyHandler中進行處理
  1. privatefinal Runnable mPowerLongPress = new Runnable() {  
  2.     publicvoid run() {  
  3.         // The context isn't read
  4.         if (mLongPressOnPowerBehavior < 0) {  
  5.             mLongPressOnPowerBehavior = mContext.getResources().getInteger(  
  6.                     com.android.internal.R.integer.config_longPressOnPowerBehavior);  
  7.         }  
  8.         switch (mLongPressOnPowerBehavior) {  
  9.         case LONG_PRESS_POWER_NOTHING:  
  10.             break;  
  11.         case LONG_PRESS_POWER_GLOBAL_ACTIONS:  
  12.             mPowerKeyHandled = true;  
  13.             performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);  
  14.             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);  
  15.             showGlobalActionsDialog();  
  16.             break;  
  17.         case LONG_PRESS_POWER_SHUT_OFF:  
  18.             mPowerKeyHandled = true;  
  19.             performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);  
  20.             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);  
  21.             mWindowManagerFuncs.shutdown();  
  22.             break;  
  23.         }  
  24.     }  
  25. };  
在處理電源長按事件時,根據mLongPressOnPowerBehavior完成不同的處理過程,mLongPressOnPowerBehavior的值是通過配置檔案來設定的,在frameworks/base/core/res/values/config.xml中有以下一段配置:


通過讀取配置檔案取得config_longPressOnPowerBehavior配置的值為1,因此將顯示關機對話方塊

  1. case LONG_PRESS_POWER_GLOBAL_ACTIONS:  
  2.     mPowerKeyHandled = true;  
  3.     performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);  
  4.     //向ActivityManagerService請求關閉所有視窗
  5.     sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);  
  6.     //顯示關機對話方塊
  7.     showGlobalActionsDialog();  
  8.     break;  
關機對話方塊顯示:
  1. void showGlobalActionsDialog() {  
  2.     //建立GlobalActions物件
  3.     if (mGlobalActions == null) {  
  4.         mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);  
  5.     }  
  6.     finalboolean keyguardShowing = keyguardIsShowingTq();  
  7.     //顯示對話方塊
  8.     mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());  
  9.     if (keyguardShowing) {  
  10.         // since it took two seconds of long press to bring this up,
  11.         // poke the wake lock so they have some time to see the dialog.
  12.         mKeyguardMediator.pokeWakelock();  
  13.     }  
  14. }  
通過GlobalActions的showDialog函式來顯示對話方塊
  1. publicvoid showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {  
  2.     mKeyguardShowing = keyguardShowing;  
  3. 相關推薦

    Android關機流程原始碼分析

    上一篇文章Android 開關機動畫顯示原始碼分析詳細介紹了開關機動畫的顯示過程,Android系統開機時,在啟動SurfaceFlinger服務過程中通過Android屬性系統方式來啟動bootanim程序,實現開機動畫顯示過程;當系統關機時,又是如

    Android Launcher載入流程原始碼分析

    Launcher載入流程分析 最近開始接手Launcher模組,為了更好的技術積累,也看到很多大神在CSDN上發的博文,就有了在CSDN寫部落格的想法,這篇博文是我在研究了一段時間Launcher3後寫的,可能有不對的,望大家拍磚。首先我們可以先參考這篇htt

    Android O: 觸控事件傳遞流程原始碼分析(上)

    前面的部落格中,我們通過例子分析了一下Android中事件傳遞的流程, 詳細內容可以參考:Android觸控事件傳遞機制簡要分析 貫穿整個Android的觸控事件分發的流程,基本可以抽象成以下的虛擬碼: public boolean dispatchT

    Android平臺類載入流程原始碼分析

    前言 其實大家都知道的Android是使用Java作為開發語言,但是他使用的虛擬機器卻並不是傳統的JVM,在4.4以前Android使用Dalvik虛擬機器,之後使用ART(Android Runtime). Dalvik和ART與傳統的JVM不同的地方在於,為了更加

    Android 9.0)Activity啟動流程原始碼分析

    前言 熟悉Activity的啟動流程和執行原理是一個合格的應用開發人員所應該具備的基本素質,其重要程度就

    Flink on Yarn模式啟動流程原始碼分析

    此文已由作者嶽猛授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 Flink on yarn的啟動流程可以參見前面的文章 Flink on Yarn啟動流程,下面主要是從原始碼角度看下這個實現,可能有的地方理解有誤,請給予指正,多謝。 --> 1.命令列啟動yarn sessi

    【輸出文件】 Android 加密 模組原始碼分析

                                       Android6.0 加密模組解析

    Android】Retrofit原始碼分析

    Retrofit簡介 retrofit n. 式樣翻新,花樣翻新 vt. 給機器裝置裝配(新部件),翻新,改型 Retrofit 是一個 RESTful 的 HTTP 網路請求框架的封裝。注意這裡並沒有說它是網路請求框架,主要原因在於網路請求的工作並不是 Retrofit

    Android】OkHttp原始碼分析

    Android為我們提供了兩種HTTP互動的方式:HttpURLConnection 和 Apache HttpClient,雖然兩者都支援HTTPS,流的上傳和下載,配置超時,IPv6和連線池,已足夠滿足我們各種HTTP請求的需求。但更高效的使用HTTP 可以讓您的應用執行更快、更節省

    大資料之Spark(三)--- Spark核心API,Spark術語,Spark三級排程流程原始碼分析

    一、Spark核心API ----------------------------------------------- [SparkContext] 連線到spark叢集,入口點. [HadoopRDD] extends RDD 讀取hadoop

    Django rest framework 的認證流程(原始碼分析一)

    一、基本流程舉例: urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^users/', views.HostView.as_view()), ] urls

    Android Doze模式原始碼分析

    轉自:https://www.cnblogs.com/l2rf/p/6373794.html   科技的仿生學無處不在,給予我們啟發。為了延長電池是使用壽命,google從蛇的冬眠中得到體會,那就是在某種情況下也讓手機進入類冬眠的情況,從而引入了今天的主題,Doze模式,Doze中

    spring-security-oauth2(三) 認證流程原始碼分析

    認證流程原始碼分析 之前的程式碼中,我們自定義了登陸路徑,自定義成功和失敗處理器以及自定義的使用者登陸資訊校驗,下面我們通過簡單的原始碼分析,來把這些串聯起來 認證流程處理說明 認證結果如何在多個請求之間共享 獲取認證使用者資訊 認證處理流程說明 spring-

    Tigase 傳送訊息的流程原始碼分析

    XMPP 的<message/>節是使用基本的”push”方法來從一個地方到另一個地方得到訊息。因為訊息通常是不告知的,它們是一種”fire-and-forget”(發射後自尋目的)的機制來從一個地方到另一個地方快速獲取資訊訊息節有五種不同的型別,通過 type 屬性來進行區分:例如 chat 型

    Android8.0 TV焦點處理流程原始碼分析

    前言 現在基本上都是觸控式螢幕手機,導致很多開發者對焦點並沒有深刻認識,但仍然存在一些非觸屏手機,還有Android TV平臺都與焦點息息相關,這裡就總結下自己看過多篇文章和自己的實踐經驗。先看兩張焦點圖。 焦點基礎及原始碼分析通過兩篇來帶大家深入認識。

    android關機流程

    android關機流程 PhoneWindowManager.java接收到長按power按鍵 PhoneWindowManager.java public int interceptKeyBeforeQueueing(KeyEvent event, int policyF

    SpringMVC框架業務流程原始碼分析學習筆記【JAVA核心】

    1.SpringMVC框架是什麼?遵循java web什麼規範?SpringMVC是一個基於Spring生態圈之上封裝的一個處理web層請求的半封裝框架。那什麼叫半封裝框架?半封裝指的SpringMVC是基於servlet處理web層這一技術體系的擴充套件與延伸——(1)基於

    Activity啟動流程原始碼分析(應用中)

    在移動應用開發中,Android四大元件之一Activity是最常用的。很多介面,如:閃屏、主介面、次功能介面等都需要Activity來作為主要的載體;介面與介面之間,即不同的Activity之間也都存在跳轉切換,弄懂這其中跳轉切換原理,將有助於我們更好的理解A

    Android開發-從原始碼分析Fragment巢狀PagerAdapter生命週期,解決重建問題

    介紹 眾所周知在Android開發中Fragment的生命週期非常複雜,複雜得甚至讓Square公司提出了我為什麼主張反對使用Android Fragment轉而提倡使用自定義View組合替代Fragment。但是沒辦法公司專案還是使用了很多Fragment巢狀

    Android Wi-Fi原始碼分析之WifiService操作Wi-Fi(一):分析Wifi.c中的wifi_load_driver()函式

    Wi-Fi原始碼分析之WifiService操作Wi-Fi(一) 分析Wifi.c中的wifi_load_driver()函式 int wifi_load_driver() { AL