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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                盡管SystemUI的表現形式與普通的Android應用程序大相徑庭,但它卻是以一個APK的形式存在于系統之中,即它與普通的Android應用程序并沒有本質上的區別。無非是通過Android四大組件中的Activity、Service、BroadcastReceiver接受外界的請求并執行相關的操作,只不過它們所接受到的請求主要來自各個系統服務而已。 SystemUI包羅萬象,并且大部分功能之間相互獨立,比如RecentPanel、TakeScreenshotService等均是按需啟動,并在完成其既定任務后退出,這與普通的Activity以及Service別無二致。比較特殊的是狀態欄、導航欄等組件的啟動方式。它們運行于一個稱之為SystemUIService的一個Service之中。因此討論狀態欄與導航欄的啟動過程其實就是SystemUIService的啟動過程。 #### 1.SystemUIService的啟動時機 那么SystemUIService在何時由誰啟動的呢?作為一個系統級別的UI組件,自然要在系統的啟動過程中來尋找答案了。 在負責啟動各種系統服務的ServerThread中,當核心系統服務啟動完成后ServerThread會通過調用ActivityManagerService.systemReady()方法通知AMS系統已經就緒。這個systemReady()擁有一個名為goingCallback的Runnable實例作為參數。顧名思義,當AMS完成對systemReady()的處理后將會回調這一Runnable的run()方法。而在這一run()方法中可以找到SystemUI的身影: **SystemServer.java-->ServerThread** ``` ActivityManagerService.self().systemReady(newRunnable() { publicvoid run() { // 調用startSystemUi() if(!headless) startSystemUi(contextF); ...... } } ``` 進一步地,在startSystemUI()方法中: **SystemServer.java-->ServerThread.startSystemUi()** ``` static final void startSystemUi(Context context) { Intentintent = new Intent(); // 設置SystemUIService作為啟動目標 intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); // 啟動SystemUIService context.startServiceAsUser(intent, UserHandle.OWNER); } ``` 可見,當核心的系統服務啟動完畢后,ServerThread通過Context.startServiceAsUser()方法完成了SystemUIService的啟動。 #### 2.SystemUIService的創建 參考SystemUIService的onCreate()的實現: **SystemUIService.java-->SystemUIService.onCreate()** ``` /* **①SERVICES數組定義了運行于SystemUIService之中的子服務列表。**當SystemUIService服務啟動 時將會依次啟動列表中所存儲的子服務 */ final Object[] SERVICES = new Object[] { 0,// 0號元素存儲的其實是一個字符串資源號,這個字符串資源存儲了實現了狀態欄/導航欄的類名 com.android.systemui.power.PowerUI.class, com.android.systemui.media.RingtonePlayer.class, }; public void onCreate() { ...... IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); try { /* **② 根據IWindowManager.hasSystemNavBar()的返回值選擇一個合適的** ** 狀態欄與導航欄的實現** */ SERVICES[0] = wm.hasSystemNavBar() ? R.string.config_systemBarComponent : R.string.config_statusBarComponent; } catch(RemoteException e) {......} finalint N = SERVICES.length; //mServices數組中存儲了子服務的實例 mServices = new SystemUI[N]; for (inti=0; i<N; i++) { Class cl = chooseClass(SERVICES[i]); try{ // **③ 實例化子服務并將其存儲在mServices數組中** mServices[i] = (SystemUI)cl.newInstance(); }catch (IllegalAccessException ex) {......} // **④ 設置Context,并通過調用其start()方法運行它** mServices[i].mContext = this; mServices[i].start(); } } ``` 除了onCreate()方法之外,SystemUIService沒有其他有意義的代碼了。顯而易見,SystemUIService是一個容器。在其啟動時,將會逐個實例化定義在SERVICIES列表中的繼承自SystemUI抽象類的子服務。在調用了子服務的start()方法之后,SystemUIService便不再做任何其他的事情,任由各個子服務自行運行。而狀態欄導航欄則是這些子服務中的一個。 值得注意的是,onCreate()方法根據IWindowManager.hasSystemNavBar()方法的返回值為狀態欄/導航欄選擇了不同的實現。進行這一選擇的原因為了能夠在大尺寸的設備中更有效地利用屏幕空間。在小屏幕設備如手機中,由于屏幕寬度有限,Android采取了狀態欄與導航欄分離的布局方案,也就是說導航欄與狀態欄占用了更多的垂直空間,使得導航欄的虛擬按鍵尺寸足夠大以及狀態欄的信息量足夠多。而在大屏幕設備如平板電腦中,由于屏幕寬度比較大,足以在一個屏幕寬度中同時顯示足夠大的虛擬按鍵以及足夠多的狀態欄信息量,此時可以選擇將狀態欄與導航欄功能集成在一起成為系統欄作為大屏幕下的布局方案,以節省對垂直空間的占用。 hasSystemNavBar()的返回值取決于PhoneWindowManager.mHasSystemNavBar成員的取值。因此在PhoneWindowManager.setInitialDisplaySize()方法中可以得知Android在兩種布局方案中進行選擇的策略。 **PhoneWindowManager.java-->PhoneWindowManager.setInitialDisplaySize()** ``` public void setInitialDisplaySize(Display display,int width , intheight, int density) { ...... // **① 計算屏幕短邊的DP寬度** intshortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density; // **② 屏幕寬度在720dp以內時,使用分離的布局方案** if(shortSizeDp < 600) { mHasSystemNavBar= false; mNavigationBarCanMove = true; } elseif (shortSizeDp < 720) { mHasSystemNavBar = false; mNavigationBarCanMove = false; } ...... } ``` 在SystemUI中,分離布局方案的實現者是PhoneStatusBar,而集成布局方案的實現者則是TabletStatusBar。二者的本質功能是一致的,即提供虛擬按鍵、顯示通知信息等,區別僅在于布局的不同、以及由此所衍生出的定制行為而已。因此不難想到,它們是從同一個父類中繼承出來的。這一父類的名字是BaseStatusBar。本章將主要介紹PhoneStatusBar的實現,讀者可以類比地對TabletStatusBar進行研究。
                  <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>

                              哎呀哎呀视频在线观看