android12 SystemUI组件之StatusBar启动

第一阶段:系统服务的启动(SystemServer 发起)

一切的起点在 SystemServer,这是 Android 框架中负责启动绝大多数核心系统服务的关键进程。

  • 启动入口 :在 SystemServerstartOtherServices() 方法中,会调用 startSystemUi(context, windowManager)
  • 获取组件startSystemUi 方法会通过 PackageManagerInternal 来获取 SystemUI 的服务组件名(SystemUIService)。
  • 发起启动 :最终,通过 context.startServiceAsUser(intent, UserHandle.SYSTEM),以系统用户身份启动了这个服务。至此,启动流程从系统进程跨入了 SystemUI 应用进程。
csharp 复制代码
//frameworks/base/services/java/com/android/server/SystemServer.java
private static void startSystemUi(Context context, WindowManagerService windowManager) {
    PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
    Intent intent = new Intent();
    //通过PMS配置获取
    intent.setComponent(pm.getSystemUiServiceComponent());
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    context.startServiceAsUser(intent, UserHandle.SYSTEM);
    windowManager.onSystemUiStarted();
}

/Users/apple/Downloads/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public ComponentName getSystemUiServiceComponent() {
    return ComponentName.unflattenFromString(mContext.getResources().getString(
            com.android.internal.R.string.config_systemUIServiceComponent));
}

//frameworks/base/core/res/res/values/config.xml
<string name="config_systemUIServiceComponent" translatable="false"
        >com.android.systemui/com.android.systemui.SystemUIService</string>

第二阶段:应用与服务的初始化(SystemUI 应用内部)

SystemUIService 被拉起后,SystemUI 这个系统应用(APK)便开始启动。

  • 应用入口 :作为应用的入口,SystemUIApplicationonCreate() 会被执行,进行一系列初始化工作。
scss 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@Override
public void onCreate() {
    super.onCreate();
    //这是一个回调,用于在 `Context` 可用时通知 Dagger2 的依赖注入框架
    mContextAvailableCallback.onContextAvailable(this);
    //`mRootComponent` 和 `mSysUIComponent` 是 Dagger2 生成的依赖注入图,
    //所有 SystemUI 组件(StatusBar、Keyguard等)都从这里获取。
    mRootComponent = SystemUIFactory.getInstance().getRootComponent();
    mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
    //`mComponentHelper`:用于通过反射动态创建 SystemUI 服务组件
    mComponentHelper = mSysUIComponent.getContextComponentHelper();
    //**`mBootCompleteCache`**:缓存系统启动完成状态,避免重复处理
    mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
    //应用层设置主题,确保所有 Service 继承该主题
    //在 Manifest 中设置主题只对 Activity 有效,Service 需要显式设置
    setTheme(R.style.Theme_SystemUI);

    if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
        //注册 BOOT_COMPLETED 广播
        IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
        //确保 SystemUI 能优先收到启动完成事件
        bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        ...
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                ...
                if (mServicesStarted) {
                    final int N = mServices.length;
                    for (int i = 0; i < N; i++) {
                     //遍历已启动的所有 SystemUI 组件(StatusBar、Keyguard等),
                     //调用它们的 `onBootCompleted()` 方法
                        mServices[i].onBootCompleted();
                    }
                }
            }
        }, bootCompletedFilter);
        //监听系统语言变更广播
        IntentFilter localeChangedFilter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
               ...
            }
        }, localeChangedFilter);
    } else {
        ...
        // 为当前非系统用户启动必要的服务
        startSecondaryUserServicesIfNeeded();
    }
}
  • 启动所有服务组件 :在 SystemUIServiceonCreate() 中,会调用 SystemUIApplication.startServicesIfNeeded()

    • startServicesIfNeeded() 会通过反射机制,将配置文件中定义的所有 SystemUI 组件(如 StatusBar, Keyguard, NotificationListener 等)实例化并启动。
    • 这些组件都继承自 SystemUI 基类,它们的 start() 方法会在此阶段被调用。
typescript 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@Override
public void onCreate() {
    super.onCreate();
    ...
    ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    ...
    
}

//frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java)
public void startServicesIfNeeded() {
          String[] names = SystemUIFactory.getInstance().getSystemUIServiceComponents(getResources());
          startServicesIfNeeded(/* metricsPrefix= */ "StartServices", names);
 }
 
 //frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java)
public String[] getSystemUIServiceComponents(Resources resources) {
          return resources.getStringArray(R.array.config_systemUIServiceComponents);
}

//frameworks/base/packages/SystemUI/res/values/config.xml
//SystemUI组件配置
<string-array name="config_systemUIServiceComponents" translatable="false">
    <item>com.android.systemui.util.NotificationChannels</item>
    <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
    <item>com.android.systemui.recents.Recents</item>
    <item>com.android.systemui.volume.VolumeUI</item>
    <item>com.android.systemui.statusbar.phone.StatusBar</item>
    <item>com.android.systemui.usb.StorageNotification</item>
    <item>com.android.systemui.power.PowerUI</item>
    <item>com.android.systemui.media.RingtonePlayer</item>
    <item>com.android.systemui.keyboard.KeyboardUI</item>
    <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
    <item>@string/config_systemUIVendorServiceComponent</item>
    <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
    <item>com.android.systemui.LatencyTester</item>
    <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
    <item>com.android.systemui.ScreenDecorations</item>
    <item>com.android.systemui.biometrics.AuthController</item>
    <item>com.android.systemui.SliceBroadcastRelayHandler</item>
    <item>com.android.systemui.theme.ThemeOverlayController</item>
    <item>com.android.systemui.accessibility.WindowMagnification</item>
    <item>com.android.systemui.accessibility.SystemActions</item>
    <item>com.android.systemui.toast.ToastUI</item>
    <item>com.android.systemui.wmshell.WMShell</item>
</string-array>

第三阶段:StatusBar 的创建与视图加载

在所有被启动的服务组件中,StatusBar 是构建状态栏和通知面板的核心。

  1. 执行 start() 方法 :在 StatusBarstart() 方法中,会调用 createAndAddWindows()
scss 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java)
public void start() {
    //监听屏幕开/关状态,控制状态栏的显示/隐藏
    mScreenLifecycle.addObserver(mScreenObserver);
    //监听系统唤醒状态(唤醒/睡眠),影响锁屏和通知行为
    mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
    //监听UI模式变化
    mUiModeManager = mContext.getSystemService(UiModeManager.class);
    ...

    mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    //屏保管理(Daydream)
    mDreamManager = IDreamManager.Stub.asInterface(
            ServiceManager.checkService(DreamService.DREAM_SERVICE));

    ...

    // start old BaseStatusBar.start().
    mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
    //设备策略管理(如禁用状态栏)
    mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
            Context.DEVICE_POLICY_SERVICE);

    ...
    //`StatusBarManagerService` 的Binder接口,用于与系统服务通信
    mBarService = IStatusBarService.Stub.asInterface(
            ServiceManager.getService(Context.STATUS_BAR_SERVICE));

    //锁屏管理
    mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
    ...

    //CommandQueue实现了 `IStatusBar` 接口
    mCommandQueue.addCallback(this);

    ...

    RegisterStatusBarResult result = null;
    try {
       //向 `StatusBarManagerService` 注册回调,返回的 `result` 包含了初始状态信息
        result = mBarService.registerStatusBar(mCommandQueue);
    } catch (RemoteException ex) {
        ex.rethrowFromSystemServer();
    }
    //创建窗口和视图
    //-   加载 `super_status_bar.xml` 根布局
    //-   创建折叠状态栏 (`CollapsedStatusBarFragment`)
    //-   创建展开面板 (`NotificationPanelView`)
    //-   通过 `StatusBarWindowController` 添加到 WindowManager
    createAndAddWindows(result);
   
    setUpPresenter();

    ...
   
    mIconPolicy.init();
   
    mKeyguardStateController.addCallback(this);
    //初始化锁屏UI,但不一定显示(取决于锁屏状态)
    startKeyguard();
    //监听锁屏状态变化(如人脸解锁、指纹等)
    mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
    //初始化息屏显示(Always-On Display)相关功能
    mDozeServiceHost.initialize(
            this,
            mStatusBarKeyguardViewManager,
            mNotificationShadeWindowViewController,
            mNotificationPanelViewController,
            mAmbientIndicationContainer);
    mDozeParameters.addCallback(this::updateLightRevealScrimVisibility);

    ...

}

public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
    //创建状态栏视图
    makeStatusBarView(result);
    //添加下拉通知面板窗口
    mNotificationShadeWindowController.attach();
    //添加状态栏窗口
    mStatusBarWindowController.attach();
}
  1. 构建核心视图createAndAddWindows() 进一步调用 makeStatusBarView(),这就是构建状态栏视图的关键入口。
scss 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
    final Context context = mContext;
    ...
    //加载 `super_status_bar.xml` 布局文件,创建 `StatusBarWindowView` 根视图
    //创建下拉面板视图,创建状态栏窗口视图
    inflateStatusBarWindow();
    //将 `StatusBar` 实例和窗口控制器注入到下拉面板窗口控制器中,建立双向引用
    mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController);
//为下拉面板根视图设置触摸监听器,处理触摸事件分发
mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());

    //初始化通知列表控制器
    mStackScrollerController =
            mNotificationPanelViewController.getNotificationStackScrollLayoutController();
    //获取 `NotificationStackScrollLayout` 视图实例
    mStackScroller = mStackScrollerController.getView();
    //获取通知列表容器接口,用于操作通知列表
    NotificationListContainer notifListContainer =
            mStackScrollerController.getNotificationListContainer();
    mNotificationLogger.setUpWithContainer(notifListContainer);

    //创建底部工具条 (Shelf)
    inflateShelf();
   //将 Shelf 控制器设置到通知图标区域控制器中,建立关联
   mNotificationIconAreaController.setupShelf(mNotificationShelfController);
   //添加面板展开监听器,用于唤醒协调器(处理亮屏/暗屏过渡) mNotificationPanelViewController.addExpansionListener(mWakeUpCoordinator);
   //添加面板展开监听器,用于在锁屏状态下面板展开时触发锁屏消失逻辑
    mNotificationPanelViewController.addExpansionListener(
            this::dispatchPanelExpansionForKeyguardDismiss);

    ...
    
    //监听 `CollapsedStatusBarFragment` 的创建完成事件
   FragmentHostManager.get(mPhoneStatusBarWindow)
        //添加标签监听器,当带有 `TAG` 的 Fragment 被创建或重新创建时触发回调
        .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
            CollapsedStatusBarFragment statusBarFragment =
                    (CollapsedStatusBarFragment) fragment;

            PhoneStatusBarView oldStatusBarView = mStatusBarView;
            //从 Fragment 中获取新创建的 `PhoneStatusBarView` 视图
            mStatusBarView = (PhoneStatusBarView) statusBarFragment.getView();
            //将 `StatusBar` 实例注入到视图,用于回调状态栏事件
            mStatusBarView.setBar(this);
            //注入面板控制器,用于面板展开状态查询
            mStatusBarView.setPanel(mNotificationPanelViewController);
            //注入遮罩控制器,用于控制遮罩层
            mStatusBarView.setScrimController(mScrimController);
            //设置展开状态变化监听器列表
            mStatusBarView.setExpansionChangedListeners(mExpansionChangedListeners);
            for (ExpansionChangedListener listener : mExpansionChangedListeners) {
            //向监听器发送当前展开状态(初始值)
                sendInitialExpansionAmount(listener);
            }

           mNotificationPanel.notifyBarPanelExpansionChanged().
           //检查是否有固定的 HeadsUp 通知(即正在显示的 HeadsUp)
            if (mHeadsUpManager.hasPinnedHeadsUp()) {
               //通知面板展开状态已变化,更新视图 mNotificationPanelViewController.notifyBarPanelExpansionChanged();
            }
            mStatusBarView.setBouncerShowing(mBouncerShowing);
            ...
          
           //设置状态栏视图到面板窗口控制器
           mNotificationShadeWindowViewController.setStatusBarView(mStatusBarView);
            checkBarModes();
        }).getFragmentManager()
        .beginTransaction()
        .replace(R.id.status_bar_container,
                //创建折叠状态栏fragment
                new CollapsedStatusBarFragment(
                        mOngoingCallController,//正在进行的通话控制器
                        mAnimationScheduler,//动画调度器
                        mStatusBarLocationPublisher,
                        mNotificationIconAreaController,//通知图标区域控制器
                        mFeatureFlags,
                        mStatusBarIconController,//状态栏图标控制器
                        mKeyguardStateController,//锁屏状态控制器
                        mNetworkController,//网络控制器(信号/WiFi)
                        mStatusBarStateController,//状态栏状态控制器
                        this,
                        mCommandQueue
                ),
                CollapsedStatusBarFragment.TAG)
        .commit();

    ...
   //创建导航栏
    createNavigationBar(result);

    ...
    //初始化遮罩层
    ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
    ScrimView notificationsScrim = mNotificationShadeWindowView
            .findViewById(R.id.scrim_notifications);
    ...

    //初始化背景
    BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
    //初始化媒体管理器,设置背景、前景、遮罩控制器和锁屏壁纸
    mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
            backdrop.findViewById(R.id.backdrop_back), mScrimController, mLockscreenWallpaper);
    ...

    //初始化快速设置面板QS
    final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
    if (container != null) {
        FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
        ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
                mExtensionController
                        .newExtension(QS.class)
                        .withPlugin(QS.class)
                        .withDefault(this::createDefaultQSFragment)
                        .build());
        //亮度滑块
        mBrightnessMirrorController = new BrightnessMirrorController(
                mNotificationShadeWindowView,
                mNotificationPanelViewController,
                mNotificationShadeDepthControllerLazy.get(),
                mBrightnessSliderFactory,
                (visible) -> {
                    mBrightnessMirrorVisible = visible;
                    updateScrimController();
                });
        ...
    }

    ...
    //注册广播接收器(屏幕开/关、时间变化等)
    registerBroadcastReceiver();
    ...

}
  1. 加载布局文件:在视图构建过程中,会加载核心布局文件。

    • 根布局super_status_bar.xml 是整个状态栏窗口的根布局,super_notification_shade.xml 是整个下栏栏窗口的根布局。
    • 折叠状态栏 :通过 CollapsedStatusBarFragment(加载 status_bar.xml)来构建我们看到的顶部状态栏。
    • 展开面板NotificationPanelView 则是下拉通知面板和快捷设置面板的根布局,对应 status_bar_expanded.xml 文件。
scss 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
private void inflateStatusBarWindow() {
   //使用工厂模式创建下拉面板视图,SuperStatusBarViewFactory
    mNotificationShadeWindowView = mSuperStatusBarViewFactory.getNotificationShadeWindowView();
    //获取构建器,将下拉面板视图作为依赖注入到组件中
    StatusBarComponent statusBarComponent = mStatusBarComponentBuilder.get()
            .statusBarWindowView(mNotificationShadeWindowView).build();
    //从组件中获取下拉面板窗口控制器
    mNotificationShadeWindowViewController = statusBarComponent
            .getNotificationShadeWindowViewController();
    
 //设置下拉面板视图到窗口控制器   mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
    //设置展开状态栏
    mNotificationShadeWindowViewController.setupExpandedStatusBar();
    //获取状态栏窗口控制器
    mStatusBarWindowController = statusBarComponent.getStatusBarWindowController();
    //创建状态栏视图
    mPhoneStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
    //获取通知面板控制器
    mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
    //初始化锁屏图标控制器
    statusBarComponent.getLockIconViewController().init();
    //管理生物识别认证时的波纹动画(如指纹解锁时的光效
    mAuthRippleController = statusBarComponent.getAuthRippleController();
    //认证波纹控制器初始化。
    mAuthRippleController.init();
}

//创建下拉面板根视图,布局super_notification_shade
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
public NotificationShadeWindowView getNotificationShadeWindowView() {
    if (mNotificationShadeWindowView != null) {
        return mNotificationShadeWindowView;
    }

    mNotificationShadeWindowView = (NotificationShadeWindowView)
            mInjectionInflationController.injectable(
            LayoutInflater.from(mContext)).inflate(R.layout.super_notification_shade,
            /* root= */ null);
    ...

    return mNotificationShadeWindowView;
}

//创建状态栏根视图,布局super_status_bar
public StatusBarWindowView getStatusBarWindowView() {
    if (mStatusBarWindowView != null) {
        return mStatusBarWindowView;
    }

    mStatusBarWindowView =
            (StatusBarWindowView) mInjectionInflationController.injectable(
            LayoutInflater.from(mContext)).inflate(R.layout.super_status_bar,
            /* root= */ null);
    ...
    return mStatusBarWindowView;
}

//加载 `status_bar.xml` 布局,管理所有子视图
//利用 Fragment 的生命周期管理状态栏的创建、销毁和重建
//响应锁屏、网络、通知等状态变化
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
        Bundle savedInstanceState) {
    return inflater.inflate(R.layout.status_bar, container, false);
}

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mStatusBar = (PhoneStatusBarView) view;
    //查找状态栏内容的根容器
    View contents = mStatusBar.findViewById(R.id.status_bar_contents);
    //添加布局变化监听器,当内容位置变化时触发
    contents.addOnLayoutChangeListener(mStatusBarLayoutListener);
    //发布状态栏的当前位置,供其他组件(如导航栏)调整
    updateStatusBarLocation(contents.getLeft(), contents.getRight());
    if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {
        mStatusBar.restoreHierarchyState(
                savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
    }
    //初始化 DarkIconManager,管理状态栏右侧的图标
    mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons), mFeatureFlags);
    mDarkIconManager.setShouldLog(true);
   //添加被阻止显示的图标类型(音量、闹钟、信号强度)
   //**音量**:音量和铃声状态通常由系统控制,不常显示
   //**闹钟**:闹钟图标在状态栏中容易与通知混淆
   //**信号强度**:信号强度由 `SignalClusterView` 单独显示mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_volume));
    mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_alarm_clock));
    mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_call_strength));
    mDarkIconManager.setBlockList(mBlockedIcons);
    //状态栏图标控制器
    mStatusBarIconController.addIconGroup(mDarkIconManager);
    //系统图标区域(右侧,包含信号、WiFi、电量等)
    mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
    mClockView = mStatusBar.findViewById(R.id.clock);
    //正在进行的通话芯片(显示通话时长等)
    mOngoingCallChip = mStatusBar.findViewById(R.id.ongoing_call_chip);
    //初始隐藏系统图标区域
    //这些组件会在系统状态更新时(如锁屏状态变化、网络连接)才显示。
    //这避免了在 Fragment 初始化时出现闪烁。
    showSystemIconArea(false);
    showClock(false);
    //初始化紧急呼叫/加密守护者文本(锁屏时显示)
    initEmergencyCryptkeeperText();
    //初始化运营商名称(在锁屏或某些状态下显示)
    initOperatorName();
    //初始化通知图标区域(左侧,显示应用通知图标)
    initNotificationIconArea();
    mAnimationScheduler.addCallback(this);
}
  1. 添加下拉通知面板窗口 :通过 NotificationShadeWindowControllerImplattach() 方法,将下拉通知面板添加到 WindowManager
scss 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
public void attach() {
    //创建窗口布局参数
    mLp = new LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT,
            //通知面板专用窗口类型,层级在状态栏下方、应用上方
            LayoutParams.TYPE_NOTIFICATION_SHADE,
            //窗口不接收焦点,触摸事件会传递到下层窗口
            LayoutParams.FLAG_NOT_FOCUSABLE
                    | LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                    | LayoutParams.FLAG_SPLIT_TOUCH
                    | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
            PixelFormat.TRANSLUCENT);
    mLp.token = new Binder();
    mLp.gravity = Gravity.TOP;
    ...
    //将下拉面板视图添加到 WindowManager
    mWindowManager.addView(mNotificationShadeView, mLp);
    //同步锁屏状态
    if (mKeyguardViewMediator.isShowingAndNotOccluded()) {
        setKeyguardShowing(true);
    }
}
  1. 添加状态栏窗口 :通过 StatusBarWindowControllerattach() 方法,将状态栏添加到 WindowManager
csharp 复制代码
//frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
public void attach() {
    //创建窗口布局参数
    mLp = new WindowManager.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            mBarHeight,
            //状态栏专用窗口类型,**系统最高层级**
            WindowManager.LayoutParams.TYPE_STATUS_BAR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                    | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
            PixelFormat.TRANSLUCENT);
    mLp.privateFlags |= PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
    mLp.token = new Binder();
    ...
    //将状态栏视视图添加到 WindowManager
    mWindowManager.addView(mStatusBarView, mLp);
    
}
  1. StatusBar等待数据驱动显示

StatusBarIconController → 显示系统图标 (信号/WiFi/电量/时钟)

NotificationIconAreaController → 显示通知图标

StatusBarWindowController状态栏窗口的核心控制器 ,它负责状态栏窗口的创建、附加、布局参数配置、显示/隐藏 以及与 WindowManager 的交互。

StatusBarIconController状态栏所有系统图标核心控制器 ,它负责将来自系统服务(如网络、电池、蓝牙等)的状态数据,转化为状态栏右侧区域显示的具体图标

NotificationIconAreaController状态栏左侧通知图标区域的核心控制器 。它负责将来自应用的通知,转化为状态栏上显示的小图标,并管理这些图标的添加、更新、移除和动画

NotificationShadeWindowViewController下拉通知面板窗口级别的控制器 ,它管理的是整个 NotificationShadeWindowView(即下拉面板的根视图),而不是面板内部的具体内容(如通知列表或 QS 面板)。

NotificationPanelViewController下拉通知面板的核心控制器 ,它管理着整个面板的展开/收起动画、手势交互、状态管理 以及与锁屏、快捷设置(QS) 的协调。它是 SystemUI 中最复杂、最重要的控制器之一。

NotificationStackScrollLayoutController :不仅仅是"通知列表的控制器",它是 SystemUI 中通知视觉呈现与交互的神经中枢 。它直接管理着 NotificationStackScrollLayout(一个自定义的 ViewGroup),负责:

  1. 通知行(ExpandableNotificationRow)的完整生命周期:创建、绑定数据、更新、移除、回收。
  2. 复杂交互逻辑:滑动删除、拖拽排序(如果启用)、通知分组展开/折叠、长按菜单。
  3. 动画编排:添加/移除动画、高度变化动画、分组展开/折叠动画。
  4. 滚动与布局:处理用户滚动、自动滚动到特定通知、响应面板展开/收起的布局调整。
  5. 状态同步 :将通知列表的状态(如当前可见通知、高度变化)实时同步给 StatusBarNotificationPanelViewControllerHeadsUpManager

QSPanelController快捷设置面板 (Quick Settings Panel) 的核心控制器,负责管理 QS 面板的 UI 逻辑、状态更新和交互响应。

相关推荐
hai_android1 小时前
Kotlin 协程上下文:从 plus 到 CombinedContext,彻底搞懂左偏结构
android·kotlin
淡淡的香烟1 小时前
AndroidKMP之网络请求
android·网络
basketball6162 小时前
AI Infra 推理部署技术总结:2. vLLM 内核——PagedAttention 与调度器原理
android·人工智能·vllm·ai infra
I'mChloe3 小时前
群晖部署 image-matting:把人像去背景做成一个随开随用的 Web 工具
android·前端
千里马-horse3 小时前
第 61 章:设备策略与 Android 企业版
android·aosp
2501_915106323 小时前
Flutter iOS混淆打包详细教程与步骤
android·flutter·ios·小程序·uni-app·iphone·webview
三少爷的鞋3 小时前
Android 架构演进:从生命周期事件到结构化任务
android
一笑的小酒馆10 小时前
AndroidKMP之网络请求
android
aqi0014 小时前
鸿蒙版本的JSBridge兼容与安卓配套的H5啦
android·华为·harmonyos·鸿蒙·移动应用