SystemUI 最通俗易懂的SystemBars启动流程

55 篇文章 37 订阅 ¥99.90 ¥99.00

不积跬步无以至千里
在这里插入图片描述
        SystemBars的启动包含了状态栏与导航栏的启动,是SystemUI中较为重要的一个功能模块,下边说一下它的启动流程.
        接着上一次讲的,上次说到每个功能模块都是继承自SystemUI.java,然后实现了start()抽象方法,然后通过循环启动了各个功能模块,而我们今天的讲的这个SystemBars肯定也是在启动之一.
一.SystemBars.java
代码路径:
code/app/src/com/android/systemui/SystemBars.java
1.

/**
 * Ensure a single status bar service implementation is running at all times, using the in-process
 * implementation according to the product config.
 */
public class SystemBars extends SystemUI {

这里说到确保一个StatusBar的服务实现一直在运行在所有时间里在这进程.
2.
循环遍历调用的start方法.

@Override
    public void start() {
        if (DEBUG) Log.d(TAG, "start");
        createStatusBarFromConfig();
    }
    
private void createStatusBarFromConfig() {
        if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
        //通过读取资源文件获取的要启动的类,com.android.systemui.statusbar.phone.StatusBar
        //android源码中还支持CarStatusBar与TvStatusBar这两种模式
        final String clsName = mContext.getString(R.string.config_statusBarComponent);
        if (clsName == null || clsName.length() == 0) {
            throw andLog("No status bar component configured", null);
        }
        Class<?> cls = null;
        try {
            cls = mContext.getClassLoader().loadClass(clsName);
        } catch (Throwable t) {
            throw andLog("Error loading status bar component: " + clsName, t);
        }
        try {
        //通过反射获取到要启动的对象.
            mStatusBar = (SystemUI) cls.newInstance();
        } catch (Throwable t) {
            throw andLog("Error creating status bar component: " + clsName, t);
        }
        mStatusBar.mContext = mContext;
        mStatusBar.mComponents = mComponents;
        //调用对象的start方法
        mStatusBar.start();
        if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
    }

二.StatusBar.java
代码路径:
app/src/com/android/systemui/statusbar/phone/StatusBar.java
1.

@Override
    public void start() {
    	//初始化各种系统服务与观察者
        mNetworkController = Dependency.get(NetworkController.class);
        mUserSwitcherController = Dependency.get(UserSwitcherController.class);
        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
        mScreenLifecycle.addObserver(mScreenObserver);
        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
        mBatteryController = Dependency.get(BatteryController.class);
        mAssistManager = Dependency.get(AssistManager.class);
        mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
        mOverlayManager = IOverlayManager.Stub.asInterface(
                ServiceManager.getService(Context.OVERLAY_SERVICE));

        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
        mColorExtractor.addOnColorsChangedListener(this);

        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);

        mForegroundServiceController = Dependency.get(ForegroundServiceController.class);
		//获取屏幕参数
        mDisplay = mWindowManager.getDefaultDisplay();
        updateDisplaySize();
        ...
        //与StatusBarManagerService注册实现通讯,状态栏的下拉禁止等等外部接口
        // Connect in to the status bar manager service
        mCommandQueue = getComponent(CommandQueue.class);
        mCommandQueue.addCallbacks(this);

        int[] switches = new int[9];
        ArrayList<IBinder> binders = new ArrayList<>();
        ArrayList<String> iconSlots = new ArrayList<>();
        ArrayList<StatusBarIcon> icons = new ArrayList<>();
        Rect fullscreenStackBounds = new Rect();
        Rect dockedStackBounds = new Rect();
        try {
            mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
                    fullscreenStackBounds, dockedStackBounds);
        } catch (RemoteException ex) {
            // If the system process isn't there we're doomed anyway.
        }
		//状态栏与导航栏的View与窗口的初始化
        createAndAddWindows();

        mCommandQueue.disable(switches[0], switches[6], false /* animate */);
        setSystemUiVisibility(switches[1], switches[7], switches[8], 0xffffffff,
                fullscreenStackBounds, dockedStackBounds);
        topAppWindowChanged(switches[2] != 0);
		...
		//初始化状态栏icon
        // Set up the initial icon state
        int N = iconSlots.size();
        for (int i=0; i < N; i++) {
            mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
        }
		//注册与NotificationManagerService实现通信,通知的刷新.
        // Set up the initial notification state.
        try {
            mNotificationListener.registerAsSystemService(mContext,
                    new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
                    UserHandle.USER_ALL);
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to register notification listener", e);
        }
        //锁屏View的初始化
        startKeyguard();

2.状态栏与导航栏View与窗口的初始化
createAndAddWindows()
1.

	public void createAndAddWindows() {
        addStatusBarWindow();
    }

    private void addStatusBarWindow() {
        makeStatusBarView();
        mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
        mRemoteInputController = new RemoteInputController(mHeadsUpManager);
        //StatusBar的窗口的添加
        mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
    }
    protected void makeStatusBarView() {
        final Context context = mContext;
        //获取屏幕的参数
        updateDisplaySize(); // populates mDisplayMetrics
        //更新一些设置,布局的参数,通知的锁屏最多显示
        updateResources();
        //更新主题,Theme_SystemUI_Light,Theme_SystemUI,有两种其中为黑色与青色.
        //其中会重新创建锁屏第一界面的图标与提示区域的对象,这里在人脸识别出现了bug
        updateTheme();
		//super_status_bar,根布局对象
        inflateStatusBarWindow(context);
        mStatusBarWindow.setService(this);
        //设置它的touch事件
        mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
        //通知的布局等初始化
        mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
                R.id.notification_panel);
        mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
                R.id.notification_stack_scroller);
        ...
        //状态栏初始化
        FragmentHostManager.get(mStatusBarWindow)
                .addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
                    CollapsedStatusBarFragment statusBarFragment =
                            (CollapsedStatusBarFragment) fragment;
                    statusBarFragment.initNotificationIconArea(mNotificationIconAreaController);
                    mStatusBarView = (PhoneStatusBarView) fragment.getView();
                    mStatusBarView.setBar(this);
                    mStatusBarView.setPanel(mNotificationPanel);
                    mStatusBarView.setScrimController(mScrimController);
                    mStatusBarView.setBouncerShowing(mBouncerShowing);
                    mStatusBarContents = mStatusBarView.findViewById(R.id.status_bar_contents);
                    mCarrierLabelView = mStatusBarContents.findViewById(R.id.ssui_carrier_label_view);
                    mNetworkController.addCarrierLabel(mCarrierLabelView);
                    setAreThereNotifications();
                    checkBarModes();
                }).getFragmentManager()
                .beginTransaction()
                .replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
                        CollapsedStatusBarFragment.TAG)
                .commit();
        mIconController = Dependency.get(StatusBarIconController.class);
        //悬浮通知管理的初始化
        mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
        mHeadsUpManager.setBar(this);
        mHeadsUpManager.addListener(this);
        mHeadsUpManager.addListener(mNotificationPanel);
        mHeadsUpManager.addListener(mGroupManager);
        mHeadsUpManager.addListener(mVisualStabilityManager);
        ...
        //创建初始化导航栏
         try {
            boolean showNav = mWindowManagerService.hasNavigationBar();
            if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
            if (showNav) {
                KeyguardUpdateMonitor.getInstance(context).registerCallback(sKeyguardCallback);

                createNavigationBar();
            }
        } catch (RemoteException ex) {
            // no window manager? good luck with that
        }
		//通知的长按
		 mStackScroller.setLongPressListener(getNotificationLongClicker());
        mStackScroller.setStatusBar(this);
        mStackScroller.setGroupManager(mGroupManager);
        mStackScroller.setHeadsUpManager(mHeadsUpManager);
        mGroupManager.setOnGroupChangeListener(mStackScroller);
        //锁屏第一屏提示文字区域对象
        mKeyguardIndicationController =
                SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
                (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
                mNotificationPanel.getLockIcon());
        ...
        //前后蒙层,以及悬浮通知蒙层
        ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
        ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
        View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
        mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController,
                scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper,
                scrimsVisible -> {
                    if (mStatusBarWindowManager != null) {
                        mStatusBarWindowManager.setScrimsVisible(scrimsVisible);
                    }
                });
      //QuickSettings的初始化
      // Set up the quick settings tile panel
        View container = mStatusBarWindow.findViewById(R.id.qs_frame);
        if (container != null) {
            FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
            ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
                    Dependency.get(ExtensionController.class).newExtension(QS.class)
                            .withPlugin(QS.class)
                            .withFeature(
                                    PackageManager.FEATURE_AUTOMOTIVE, () -> new CarQSFragment())
                            .withDefault(() -> new QSFragment())
                            .build());
            final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
                    mIconController);
            mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow,
                    mScrimController);
            fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
                QS qs = (QS) f;
                if (qs instanceof QSFragment) {
                    ((QSFragment) qs).setHost(qsh);
                    mQSPanel = ((QSFragment) qs).getQsPanel();
                    mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
                    mKeyguardStatusBar.setQSPanel(mQSPanel);
                }
            });
        }
		...

3.根布局
super_status_bar.xml

<com.android.systemui.statusbar.phone.StatusBarWindowView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:sysui="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.android.systemui.statusbar.BackDropView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            sysui:ignoreRightInset="true"
            >
        <ImageView android:id="@+id/backdrop_back"
                   android:layout_width="match_parent"
                   android:scaleType="centerCrop"
                   android:layout_height="match_parent" />
        <ImageView android:id="@+id/backdrop_front"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent"
                   android:scaleType="centerCrop"
                   android:visibility="invisible" />
    </com.android.systemui.statusbar.BackDropView>
	<!--后蒙层-->
    <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:importantForAccessibility="no"
        sysui:ignoreRightInset="true"
        />
	<!--悬浮通知蒙层-->
    <com.android.systemui.statusbar.AlphaOptimizedView
        android:id="@+id/heads_up_scrim"
        android:layout_width="match_parent"
        android:layout_height="@dimen/heads_up_scrim_height"
        android:background="@drawable/heads_up_scrim"
        sysui:ignoreRightInset="true"
        android:importantForAccessibility="no"/>
	<!--状态栏-->
    <FrameLayout
        android:id="@+id/status_bar_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
	<!--亮度调节-->
    <include layout="@layout/brightness_mirror" />
	<!--多用户切换-->
    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
              android:layout="@layout/car_fullscreen_user_switcher"
              android:layout_width="match_parent"
              android:layout_height="match_parent"/>
	<!--状态栏展开,里面有锁屏时间,owner显示区域,-->
    <include layout="@layout/status_bar_expanded"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible" />

    <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_in_front"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:importantForAccessibility="no"
        sysui:ignoreRightInset="true"
        />

</com.android.systemui.statusbar.phone.StatusBarWindowView>

SystemBars的初始化就先到这.

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SystemUI启动流程主要包括以下几个步骤: 1. 系统启动:当 Android 设备启动时,SystemUI 会在系统初始化的过程中被启动。 2. SystemServer 启动SystemServer 是 Android 系统中的一个关键进程,负责启动和管理系统的各个服务和组件。在 SystemServer 的初始化过程中,会启动 SystemUI。 3. SystemUI 启动SystemUI 的入口类是 `SystemUIApplication`,它继承自 `Application` 类。SystemServer 在启动 SystemUI 时会创建一个 `SystemUIApplication` 实例,并调用其 `onCreate()` 方法。 4. 初始化过程:在 `onCreate()` 方法中,SystemUIApplication 会进行一系列初始化操作,包括注册广播接收器、创建状态栏和导航栏的视图等。 5. 加载布局:SystemUI 会加载布局文件来创建状态栏和导航栏的视图。布局文件通常使用 XML 格式进行定义,可以通过 XML 布局文件中的标签和属性来描述界面元素的位置、大小和样式等。 6. 注册监听器:SystemUI 会注册一些监听器来监听系统状态的变化,例如监听通知栏的展开和收起、监听导航栏按钮的点击等。 7. 启动服务和线程:SystemUI启动一些后台服务和线程来处理各种任务,例如处理通知的显示和管理、处理导航栏的手势事件等。 8. 显示界面:SystemUI 完成初始化后,会显示状态栏和导航栏的视图,并开始接收用户的交互操作。 通过以上步骤,SystemUI 完成了启动流程,并开始提供系统界面的显示和管理功能。需要注意的是,SystemUI启动流程可能会因 Android 版本和设备厂商的定制而略有差异,以上流程仅为一般情况的示意。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rom_Fisher

赠人玫瑰,手留余香。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值