Android Statusbar介绍

1. 介绍

Android中的Statusbar包含导航栏(NavigationBar, 位于左侧、右侧或者底部)和状态栏(StatusBar, 位于顶部, 可下拉)两个部分, 位于SystemUI(frameworks/base/packages/SystemUI)模块

2. 初始化

SystemServer::startOtherServices()
  SystemServer::startSystemUi("com.android.systemui.SystemUIService")
    SystemUIService::onCreate()
      /* 
       * 加载并启动config_systemUIServiceComponents定义的服务列表
       * frameworks/base/packages/SystemUI/res/values/config.xml
       * <!-- SystemUI Services: The classes of the stuff to start. -->
       * <string-array name="config_systemUIServiceComponents" translatable="false">
       *     <item>com.android.systemui.Dependency</item>
       *     <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
       *     ......
       *     <item>com.android.systemui.SystemBars</item>
       *     ......
       *     <item>com.android.systemui.keyboard.KeyboardUI</item>
       *     ......
       * </string-array>
       */
      SystemUIApplication::startServicesIfNeeded()
        com.android.systemui.SystemBars::start()
          /* 
           * 启动config_statusBarComponent定义的服务
           * frameworks/base/packages/SystemUI/res/values/config.xml
           * <string name="config_statusBarComponent" translatable="false">
           *     com.android.systemui.statusbar.phone.StatusBar
           * </string>
           *
           * 在Automotive中被overlay, CarStatusBar继承自StatusBar
           * <string name="config_statusBarComponent" translatable="false">
           *     com.android.systemui.statusbar.car.CarStatusBar
           * </string>
           */
          SystemBars::createStatusBarFromConfig()
            CarStatusBar::start()
              StatusBar::start()
                StatusBar::createAndAddWindows()
                  StatusBar::addStatusBarWindow()
                    CarStatusBar::makeStatusBarView()
                      StatusBar::makeStatusBarView()
----------------------------------------------------------------------------
                        +++ NavigationBar +++
----------------------------------------------------------------------------
                        WindowManagerService::hasNavigationBar()
                          /* 
                           * frameworks/base/core/res/res/values/config.xml
                           * <bool name="config_showNavigationBar">false</bool>
                           *
                           * 在Automotive中被overlay
                           * <bool name="config_showNavigationBar">true</bool>
                           */
                          PhoneWindowManager::hasNavigationBar()
                        CarStatusBar::createNavigationBar()
                          /* 
                           * frameworks/base/packages/SystemUI/res/values/config.xml
                           * 根据如下配置决定是导航栏的位置,Automotive中会被overlay
                           *   config_enableBottomNavigationBar
                           *   config_enableLeftNavigationBar
                           *   config_enableRightNavigationBar
                           * 然后通过WindowManager::addView()添加创建窗口
                           *   WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
                           *   WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL
                           */
                          CarStatusBar::buildNavBarWindows()
                          CarStatusBar::buildNavBarContent()
                          CarStatusBar::attachNavBarWindows()
----------------------------------------------------------------------------
                      +++ StatusBar +++
----------------------------------------------------------------------------
                          /* 加载super_status_bar.xml实例化为状态栏的根控件 */
                          StatusBar::inflateStatusBarWindow()
                      /* 
                       * 通过WindowManager::addView()添加窗口, 类型如下
                       *   WindowManager.LayoutParams.TYPE_STATUS_BAR
                       */
                      StatusBarWindowManager::add()

3. 显示和隐藏

3.1 应用实例

应用可以通过如下的方式隐藏状态栏和导航栏

// Android < 4:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                     WindowManager.LayoutParams.FLAG_FULLSCREEN);

// 4 =< Android < 11:
int uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
getWindow().getDecorView().setSystemUiVisibility(uiFlags);

// Android >= 11
/*
 * systemBars包含statusBars和navigationBars
 */
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.show(WindowInsetsCompat.Type.systemBars())

3.2 调用流程

View::setSystemUiVisibility()
  ViewRootImpl::recomputeViewAttributes()
    ViewRootImpl::scheduleTraversals()
      ViewRootImpl::doTraversal()
            ViewRootImpl::performTraversals()
            ViewRootImpl::collectViewAttributes()
              View::dispatchCollectViewAttributes()
                View::performCollectViewAttributes()
              // Do Something
              View::dispatchWindowSystemUiVisiblityChanged()
            ViewRootImpl::relayoutWindow()
              IWindowSession::relayout()
                com.android.server.wm.Session::relayout()
                  WindowManagerService::relayoutWindow()
                    PhoneWindowManager::adjustWindowParamsLw()
----------------------------------------------------------------------------
                +++ How to get here +++
----------------------------------------------------------------------------
                PhoneWindowManager::updateSystemUiVisibilityLw()
                  StatusBarManagerService::setSystemUiVisibility()
                    IStatusBar::setSystemUiVisibility()
                      CommandQueue::setSystemUiVisibility()
                        StatusBar::setSystemUiVisibility()
                          StatusBar::notifyUiVisibilityChanged()
                            WindowManagerService::statusBarVisibilityChanged()
                              PhoneWindowManager::adjustSystemUiVisibilityLw()
                              WindowManagerService::updateStatusBarVisibilityLocked()
                                InputManagerService::setSystemUiVisibility()
                                DisplayContent::updateSystemUiVisibility()
                                  ViewRootImpl::W::dispatchSystemUiVisibilityChanged()
                                    ViewRootImpl::dispatchSystemUiVisibilityChanged()
                                      ViewRootImpl::handleDispatchSystemUiVisibilityChanged()
                                        View::updateLocalSystemUiVisibility()
                                        View::dispatchSystemUiVisibilityChanged()
                                          OnSystemUiVisibilityChangeListener::onSystemUiVisibilityChange()

参考:
<Android 9.0 SystemUI分析>
<StatusBar状态栏部分功能记录>
<Android 显示、隐藏状态栏和导航栏>
<Android SystemUI(一):图文并茂的介绍>
<API 30新特性:WindowInsetsController>

上一篇:2021-03-15


下一篇:wxWidgets:wxStatusBar 示例