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>