zoukankan      html  css  js  c++  java
  • 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>

  • 相关阅读:
    如何在.netcore 上实现 Rbac 权限管理
    socket编程之TCP开发中的PEEK_MSG的使用与见解
    简述单例模式的一些优缺点及其评价
    排查线上内存泄漏,RingBufferLogEvent类内存占用过高,skyWalking内存占用过高
    Centos7安装docker(报错:container-selinux >= 2:2.74)
    JSP3.4
    Java SM2加密、解密、签名、验签
    获取properties文件中的
    五种生成唯一id方式的对比
    SpringBoot 改造成 https访问
  • 原文地址:https://www.cnblogs.com/hzl6255/p/15027685.html
Copyright © 2011-2022 走看看