<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                如7.1.1節所述,狀態欄與導航欄的啟動由其PhoneStatusBar.start()完成。參考其實現: **PhoneStatusBar.java-->PhoneStatusBar.start()** ``` public void start() { ...... // **① 調用父類BaseStatusBar的start()方法進行初始化。** super.start(); // 創建導航欄的窗口 addNavigationBar(); // **② 創建PhoneStatusBarPolicy。**PhoneStatusBarPolicy定義了系統通知圖標的設置策略 mIconPolicy = new PhoneStatusBarPolicy(mContext); } ``` 參考BaseStatusBar.start()的實現,這段代碼比較長,并且涉及到了本章隨后會詳細介紹的內容。因此倘若讀者閱讀起來比較吃力可以僅關注那三個關鍵步驟。在完成本章的學習之后再回過頭來閱讀這部分代碼便會發現十分簡單了。 **BaseStatusBar-->BaseStatusBar.start()** ``` public void start() { /* 由于狀態欄的窗口不屬于任何一個Activity,所以需要使用第6章所介紹的WindowManager 進行窗口的創建 */ mWindowManager = (WindowManager)mContext .getSystemService(Context.WINDOW_SERVICE); /* 在第4章介紹窗口的布局時曾經提到狀態欄的存在對窗口布局有著重要的影響。因此狀態欄中 所發生的變化有必要通知給WMS */ mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); ...... /*mProvisioningOberver是一個ContentObserver。 它負責監聽Settings.Global.DEVICE_PROVISIONED設置的變化。這一設置表示此設備是否已經 歸屬于某一個用戶。比如當用戶打開一個新購買的設備時,初始化設置向導將會引導用戶閱讀使用條款、 設置帳戶等一系列的初始化操作。在初始化設置向導完成之前, Settings.Global.DEVICE_PROVISIONED的值為false,表示這臺設備并未歸屬于某 一個用戶。 當設備并未歸屬于某以用戶時,狀態欄會禁用一些功能以避免信息的泄露。mProvisioningObserver 即是用來監聽設備歸屬狀態的變化,以禁用或啟用某些功能 */ mProvisioningObserver.onChange(false); // set up mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true, mProvisioningObserver); /* **① 獲取IStatusBarService的實例。**IStatusBarService是一個系統服務,由ServerThread 啟動并常駐system_server進程中。IStatusBarService為那些對狀態欄感興趣的其他系統服務定 義了一系列API,然而對SystemUI而言,它更像是一個客戶端。因為IStatusBarService會將操作 狀態欄的請求發送給SystemUI,并由后者完成請求 */ mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); /* 隨后BaseStatusBar將自己注冊到IStatusBarService之中。以此聲明本實例才是狀態欄的真正 實現者,IStatusBarService會將其所接受到的請求轉發給本實例。 “天有不測風云”,SystemUI難免會因為某些原因使得其意外終止。而狀態欄中所顯示的信息并不屬于狀態 欄自己,而是屬于其他的應用程序或是其他的系統服務。因此當SystemUI重新啟動時,便需要恢復其 終止前所顯示的信息以避免信息的丟失。為此,IStatusBarService中保存了所有的需要狀態欄進行顯 示的信息的副本,并在新的狀態欄實例啟動后,這些副本將會伴隨著注冊的過程傳遞給狀態欄并進行顯示, 從而避免了信息的丟失。 從代碼分析的角度來看,這一從IstatusBarService中取回信息副本的過程正好完整地體現了狀態欄 所能顯示的信息的類型*/ /*iconList是向IStatusBarService進行注冊的參數之一。它保存了用于顯示在狀態欄的系統狀態 區中的狀態圖標列表。在完成注冊之后,IStatusBarService將會在其中填充兩個數組,一個字符串 數組用于表示狀態的名稱,一個StatusBarIcon類型的數組用于存儲需要顯示的圖標資源。 關于系統狀態區的工作原理將在7.2.3節介紹*/ StatusBarIconList iconList = new StatusBarIconList(); /*notificationKeys和StatusBarNotification則存儲了需要顯示在狀態欄的通知區中通知信息。 前者存儲了一個用Binder表示的通知發送者的ID列表。而notifications則存儲了通知列表。二者 通過索引號一一對應。關于通知的工作原理將在7.2.2節介紹 */ ArrayList<IBinder> notificationKeys = newArrayList<IBinder>(); ArrayList<StatusBarNotification> notifications = newArrayList<StatusBarNotification>(); /*mCommandQueue是CommandQueue類的一個實例。CommandQueue繼承自IStatusBar.Stub。 因此它是IStatusBar的Bn端。在完成注冊后,這一Binder對象的Bp端將會保存在 IStatusBarService之中。因此它是IStatusBarService與BaseStatusBar進行通信的橋梁。 */ mCommandQueue= new CommandQueue(this, iconList); /*switches則存儲了一些雜項:禁用功能列表,SystemUIVisiblity,是否在導航欄中顯示虛擬的 菜單鍵,輸入法窗口是否可見、輸入法窗口是否消費BACK鍵、是否接入了實體鍵盤、實體鍵盤是否被啟用。 在后文中將會介紹它們的具體影響 */ int[]switches = new int[7]; ArrayList<IBinder> binders = new ArrayList<IBinder>(); try { // **② 向IStatusBarServie進行注冊,并獲取所有保存在IStatusBarService中的信息副本** mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys,notifications, switches, binders); } catch(RemoteException ex) {......} // **③ 創建狀態欄與導航欄的窗口。**由于創建狀態欄與導航欄的窗口涉及到控件樹的創建,因此它由子類 PhoneStatusBar或TabletStatusBar實現,以根據不同的布局方案選擇創建不同的窗口與控件樹 */ createAndAddWindows(); /*應用來自IStatusBarService中所獲取的信息 mCommandQueue已經注冊到IStatusBarService中,狀態欄與導航欄的窗口與控件樹也都創建完畢 因此接下來的任務就是應用從IStatusBarService中所獲取的信息 */ disable(switches[0]); // 禁用某些功能 setSystemUiVisibility(switches[1], 0xffffffff); // 設置SystemUIVisibility topAppWindowChanged(switches[2]!= 0); // 設置菜單鍵的可見性 // 根據輸入法窗口的可見性調整導航欄的樣式 setImeWindowStatus(binders.get(0), switches[3], switches[4]); // 設置硬件鍵盤信息。 setHardKeyboardStatus(switches[5] != 0, switches[6] != 0); // 依次向系統狀態區添加狀態圖標 int N = iconList.size(); ...... // 依次向通知欄添加通知 N = notificationKeys.size(); ...... /* 至此,與IStatusBarService的連接已建立,狀態欄與導航欄的窗口也已完成創建與顯示,并且 保存在IStatusBarService中的信息都已完成了顯示或設置。狀態欄與導航欄的啟動正式完成 */ } ``` 可見,狀態欄與導航欄的啟動分為如下幾個過程: - 獲取IStatusBarService,IStatusBarService是運行于system\_server的一個系統服務,它接受操作狀態欄/導航欄的請求并將其轉發給BaseStatusBar。為了保證SystemUI意外退出后不會發生信息丟失,IStatusBarService保存了所有需要狀態欄與導航欄進行顯示或處理的信息副本。 - 將一個繼承自IStatusBar.Stub的CommandQueue的實例注冊到IStatusBarService以建立通信,并將信息副本取回。 - 通過調用子類的createAndAddWindows()方法完成狀態欄與導航欄的控件樹及窗口的創建與顯示。 - 使用從IStatusBarService取回的信息副本。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看