国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念)

這篇具有很好參考價值的文章主要介紹了Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念)

更新歷史 日期 內(nèi)容
1 2023-9-11 增加文中提及的漸變動畫的效果圖

在上兩篇文章中,我們介紹SystemUI的啟動過程,以及基本的組件依賴關(guān)系?;镜囊蕾囮P(guān)系請讀者一定要掌握,因為后面的文章,將會時常出現(xiàn)這些依賴關(guān)系的使用,屆時將會一筆帶過,而不會詳細(xì)說明他們的實現(xiàn)細(xì)節(jié)和原理。

接下來我們將介紹,SystemUI中各個UI部分是如何被加入屏幕中的,以及查看下拉狀態(tài)中的各個圖標(biāo)的實現(xiàn)。

但是在進(jìn)入真正的主題之前,我們還需要了解SystemUI中的各個UI的基本布局以及名字,只有了解了這些基本布局和名字,才能夠在許多相似名字中分清楚具體的對象是誰。

接下來我們將介紹SystemUI的基本布局設(shè)計,看看整個SystemUI的布局被大致分成了哪些內(nèi)容,以及這些內(nèi)容對應(yīng)的業(yè)務(wù)是什么。

SystemUI的window劃分

在“Android 12 源碼分析 —— 應(yīng)用層 二(SystemUI大體組織和啟動過程)http://t.csdn.cn/chk6Y”文章中,我們提及過,SystemUI可以通過WindowManager來顯示自己的UI。

事實上,SystemUI正是通過WindowManager來添加自己的主要的UI視圖。在SystemUI中,將以下幾個部分,分別放置在不同的Window中,然后通過WindowManager將其添加到屏幕上。

  1. StatusBar——狀態(tài)欄
  2. NotificationShade——通知卷簾(我們常說的下拉狀態(tài)欄)
  3. NavigationBar——導(dǎo)航欄

注意:除了上面三個常見的window以外,還有其他的window,如GlobalActionDialog(負(fù)責(zé)顯示——關(guān)機(jī),重啟的彈框),VolumeDialog(顯示音量調(diào)節(jié)),這些window將會在我們介紹各個子主題的時候,依次登場

可能會有讀者疑惑:鎖屏呢?不在一個單獨window下面嗎?事實上,鎖屏不在一個單獨的window中,其本身就是NotificationShade(通知卷簾,即下拉狀態(tài)欄)。換句話說,鎖屏的內(nèi)容和下拉狀態(tài)欄的內(nèi)容在同一個window中。

這里一定要注意的一點是:對應(yīng)的中文命名方式,從此刻開始,將在對應(yīng)的類后面用小括號標(biāo)記其中文命名,之所以有這樣的標(biāo)記,是因為英文名字有很多相似之處,可能不利于記憶,如:StatusBar雖然叫做狀態(tài)欄,但是在不同的Window中有不同的StatusBar(狀態(tài)欄),比如,在鎖屏狀態(tài)下有KeyguardViewStatusBar(鎖屏狀態(tài)欄);同樣地,在NotificationShade(通知卷簾,即下拉狀態(tài)欄)中本應(yīng)該顯示StatusBar(狀態(tài)欄)的地方,并不叫StatusBar。而為了便于記憶,將其中文名字放在小括號中

為了便于理解,現(xiàn)在window標(biāo)記出來,如下:
Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局
Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

有了上面的直觀感受,我們將結(jié)合SystemUI的layout文件,大體的介紹其UI布局及其相關(guān)概念,有了這些概念,才能夠在紛繁復(fù)雜的源碼中,找到對應(yīng)的實現(xiàn)實體。

SystemUI的命名規(guī)則和設(shè)計模式

本文主題是SystemUI的布局介紹,但依然可能會存在這樣的疑問:這些布局是什么時候被加載的?他們的加載流程是怎樣的?

在后面的文章中,我們會依次介紹這些布局的加載,以及怎么處理各種事件,但再此之前,需要明白他們之間的設(shè)計模式和命名規(guī)則。

SystemUI各個小模塊采用:MVC,MVP等設(shè)計模式,因此在他們的命名體系中,經(jīng)常以xxxView,xxxController,xxxPresenter來代表。例如,代表StatusBar(狀態(tài)欄)的StatusBarWindowView(狀態(tài)欄窗口視圖),StatusBarWindowController(狀態(tài)欄窗口控制器),而與StatusBarWindow相關(guān)的model即為StatusBar(狀態(tài)欄)

當(dāng)然,SystemUI編輯歷史長,中間有幾次大的修改,并不是所有的類,都遵循這些規(guī)則,不過讀者在閱讀源碼的時候,可以按照這些思路進(jìn)行思考。

而本文以介紹SystemUI布局為主題,而不關(guān)心這些布局的加載時刻和流程,但我們會用一段小提示來,簡略的概括這些布局的加載流程。在閱讀這些簡略加載流程的時候,會出現(xiàn)很多相似的名字,因此可以按照上面的命名規(guī)則來對應(yīng)相應(yīng)的實體

讀者可以忽略這些加載流程,因為在后續(xù)的文章中,將會詳細(xì)的介紹這些UI的加載流程和用戶操作

我們先從最復(fù)雜的NotificationShade(通知卷簾,下拉狀態(tài)欄)介紹起。

SystemUI的NotificationShade(通知卷簾,即下拉狀態(tài)欄)window的詳細(xì)布局

NotificationShade(通知卷簾,即下拉狀態(tài)欄)window的的加載流程

按照上文的說明,會先簡略介紹,這個布局的加載流程,如下:

  1. SytemUIService啟動之后,調(diào)用SystemUIApplication的startServicesIfNeeded()啟動相應(yīng)的服務(wù)(“Android 12 源碼分析 —— 應(yīng)用層 二(SystemUI大體組織和啟動過程)http://t.csdn.cn/chk6Y”)
  2. 啟動的服務(wù)中,有一個叫做StatusBar,它會在第一步中,被調(diào)用start()方法
  3. 在start()方法中,會調(diào)用createAndAddWindows()方法
  4. createAndAddWindows()方法會調(diào)用makeStatusBarView()方法
  5. makeStatusBarView()方法會調(diào)用inflateStatusBarWindow()方法
  6. inflateStatusBarWindow()方法會調(diào)用SuperStatusBarViewFactory的getNotificationShadeWindowView()方法
  7. getNotificationShadeWindowView()方法會去加載并解析R.layout.super_notification_shade,也即super_notification_shade.xml
  8. 第7步完成之后,會回到第4步中,并調(diào)用NotificationShadeWindowController的attach()方法,將對應(yīng)的UI,添加到屏幕上

注意:對于上面的調(diào)用過程,讀者可以完全不用在意,因為后面的文章,將會詳細(xì)介紹

接下來分析,super_notification_shade.xml

NotificationShade(通知卷簾,即下拉狀態(tài)欄)window的頂層視圖

super_notification_shade.xml的源文件如下:

注意:為了減輕閱讀障礙,我會省略掉一些非常常見的代碼,如一些屬性的定義和賦值,省略一些非常簡單的布局視圖

<com.android.systemui.statusbar.phone.NotificationShadeWindowView>

    <com.android.systemui.statusbar.BackDropView>
        
    </com.android.systemui.statusbar.BackDropView>

    <com.android.systemui.scrim.ScrimView
        android:id="@+id/scrim_behind" />

    <com.android.systemui.scrim.ScrimView
        android:id="@+id/scrim_notifications"/>

    <com.android.systemui.statusbar.LightRevealScrim
            android:id="@+id/light_reveal_scrim" />

    <include layout="@layout/status_bar_expanded"/>

    <include layout="@layout/brightness_mirror_container" />

    <com.android.systemui.scrim.ScrimView
        android:id="@+id/scrim_in_front" />

    <!-- Keyguard messages -->
    <FrameLayout>
        <com.android.keyguard.KeyguardMessageArea
            android:id="@+id/keyguard_message_area"/>
    </FrameLayout>

    <com.android.systemui.biometrics.AuthRippleView/>
</com.android.systemui.statusbar.phone.NotificationShadeWindowView>

從上面的代碼結(jié)構(gòu)看,非常滴簡單,我們依次介紹如下:

  1. NotificationShadeWindowView:通知卷簾窗口,即下拉狀態(tài)欄窗口的最頂層視圖

  2. BackDropView:幕布視圖,它會顯示最最底部的一些背景,如播放音樂的時候,顯示音樂的專輯圖片

  3. ScrimView:總共有三個,他們主要負(fù)責(zé)遮罩,如在鎖屏狀態(tài)下,整個鎖屏界面,稍微變暗淡一些,即通過設(shè)置遮罩的透明度來實現(xiàn)

  4. LightRevealScrim:也是遮罩相關(guān)的視圖,它負(fù)責(zé)處理一些漸變的動畫,如在設(shè)置中打開息屏顯示,那么在點擊電源按鈕的時候,將會顯示對應(yīng)的動畫,如下圖
    Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

  5. status_bar_expanded.xml:即展開的狀態(tài)中的布局,這里面詳細(xì)列出了下拉狀態(tài)欄之后,應(yīng)該顯示哪些內(nèi)容

  6. brightness_mirror_container.xml:這個是調(diào)節(jié)亮度條對應(yīng)的鏡像視圖,因為還有一個亮度調(diào)節(jié)條他在status_bar_expanded中,之所以有這個,是為了在調(diào)節(jié)亮度的時候,隱藏status_bar_expanded中的內(nèi)容

  7. KeyguardMessageArea:鎖屏信息顯示區(qū)域,如輸入pin錯誤,則會在此處顯示wrong pin

除了第七點,可以直接給出參考圖以外,其他的都無法給出特別好的參考圖,因此可以使用文末推薦的布局查看工具,進(jìn)行查看

在上面中出現(xiàn)了兩個include的xml文件,如果每個文件都介紹,將會消耗大量的篇幅,同時又有些詳略不得當(dāng),因此,針對一些簡單的layout文件,將會一筆帶過,如上面的brightness_mirror_container.xml文件。而這些略過的文件,在某些子主題下,將會詳細(xì)介紹,如上面的brightness_mirror_container.xml將會在調(diào)節(jié)音量的文章中,詳細(xì)介紹

因此接下來將會介紹status_bar_expanded.xml文件

status_bar_expanded.xml文件分析

status_bar_expanded.xml文件原文如下:

注意:這里依然會省略掉一些屬性定義和賦值

<com.android.systemui.statusbar.phone.NotificationPanelView
    android:id="@+id/notification_panel">
    <FrameLayout
        android:id="@+id/big_clock_container" />

    <ViewStub
        android:id="@+id/keyguard_qs_user_switch_stub"/>

    <include
        layout="@layout/keyguard_bottom_area"
        android:visibility="gone" />

    <ViewStub
        android:id="@+id/keyguard_user_switcher_stub" />

    <include layout="@layout/status_bar_expanded_plugin_frame"/>

    <include layout="@layout/dock_info_bottom_area_overlay" />

    <com.android.keyguard.LockIconView
        android:id="@+id/lock_icon_view">
    </com.android.keyguard.LockIconView>

    <com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
        android:id="@+id/notification_container_parent">

        <include layout="@layout/keyguard_status_view"/>

        <include layout="@layout/dock_info_overlay" />

        <FrameLayout android:id="@+id/qs_frame"/>

        <androidx.constraintlayout.widget.Guideline 
            android:id="@+id/qs_edge_guideline"/>

        <com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
            android:id="@+id/notification_stack_scroller"/>

        <include layout="@layout/ambient_indication"
            android:id="@+id/ambient_indication_container" />

        <include layout="@layout/photo_preview_overlay" />

        <include
            layout="@layout/keyguard_status_bar"
            android:visibility="invisible" />

        <Button
            android:id="@+id/report_rejected_touch"/>
        <com.android.systemui.statusbar.phone.TapAgainView
            android:id="@+id/shade_falsing_tap_again"/>
    </com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>

    <FrameLayout
        android:id="@+id/preview_container">
    </FrameLayout>
</com.android.systemui.statusbar.phone.NotificationPanelView>

對上面文件的介紹如下:

  1. NotificationPanelView:整個通知欄和快速設(shè)置圖標(biāo)的頂層目錄
  2. id為big_clock_container的FrameLayout:顯示一個較大的時鐘視圖
  3. 兩個ViewStub:這個跟多用戶的切換視圖有關(guān),當(dāng)點擊多用戶的時候,會在這兩個ViewStub之一中,顯示切換的視圖
  4. keyguard_bottom_area.xml:顯示鎖屏底部區(qū)域,如充電中…
  5. status_bar_expanded_plugin_frame.xml:跟SystemUI的插件有關(guān),現(xiàn)在讀者可以不用管,后面會詳細(xì)介紹其細(xì)節(jié)
  6. dock_info_bottom_area_overlay.xml:空的
  7. LockIconView:鎖屏界面下的鎖圖標(biāo)
  8. NotificationsQuickSettingsContainer:通知和快速設(shè)置的容器,其中顯示通知和快速設(shè)置
  • keyguard_status_view.xml:顯示鎖屏相關(guān)的狀態(tài)視圖,如顯示日期
  • dock_info_overlay.xml: 空的
  • id為qs_frame的FrameLayout:用于快速設(shè)置的父容器
  • Guideline:用于調(diào)整布局的視圖
  • NotificationStackScrollLayout:用于顯示通知的父容器
  • ambient_indication.xml:空的
  • photo_preview_overlay.xml:空的
  • keyguard_status_bar.xml:鎖屏狀態(tài)下的,狀態(tài)欄
  • Button:調(diào)試使用,不用管
  • TapAgainView:顯示,再按一次的視圖,現(xiàn)在已經(jīng)不用了
  1. id為preview_container的FrameLayout:預(yù)覽圖片顯示視圖,如滑動相機(jī)圖片,會先顯示一個相機(jī)的圖片

注意:對于上面某些xml文件的說明為:空的,一方面,部分內(nèi)容已經(jīng)不再使用,另一方面,部分內(nèi)容將會在后續(xù)文章中出現(xiàn)。

在上面的xml文件中,細(xì)心的讀者可能已經(jīng)注意到,即鎖屏也是在NotificationShade窗口中的。為了能夠直觀的觀察上面的內(nèi)容,我們使用圖片進(jìn)行說明,如下圖:
Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

在上面的源碼中,出現(xiàn)了

  1. keyguard_bottom_area.xml
  2. status_bar_expanded_plugin_frame.xml
  3. dock_info_bottom_area_overlay.xml
  4. keyguard_status_view.xml
  5. dock_info_overlay.xml
  6. ambient_indication.xml
  7. photo_preview_overlay.xml
  8. keyguard_status_bar.xml
    在上面文件,其中status_bar_expanded_plugin_frame.xml,dock_info_bottom_area_overlay.xml,dock_info_overlay.xml,ambient_indication.xml,photo_preview_overlay.xml一部分沒有被使用,一部分將會在后面的子主題中介紹,現(xiàn)在略過并不影響閱讀和理解

剩下的keyguard_bottom_area.xml,keyguard_status_view.xml和keyguard_status_bar.xml三個文件,簡單明了,能夠非常容易的將UI對應(yīng)上,因此不在此處介紹。這并不影響本文的閱讀和理解。不過不用擔(dān)心,在后續(xù)的文章中,我們還會介紹這三個文件,看看他們的交互和初始化過程,此處為了整體行文的緊湊,將其略去

雖然我們已經(jīng)能夠?qū)㈡i屏相關(guān)的UI和代碼建立一個聯(lián)系,但是我們現(xiàn)在還不能將下拉設(shè)置中的UI和代碼建立聯(lián)系。接下來,我們處理這部分內(nèi)容。

QuickSettings(快速設(shè)置)的布局分析

在上面的代碼中,已經(jīng)介紹了id為qs_frame的FrameLayout將用來顯示快速設(shè)置,接下來看看他們是如何布局的。

注意:NotificationStackScrollLayout的布局細(xì)節(jié)將會在后文中詳解

QuickSettings的加載流程

在上文我們知道,id為qs_frame的FrameLayout并沒有使用include來加載一個layout,因為我們需要先簡單說明一下,其加載過程,然后在看其布局結(jié)構(gòu)

  1. SytemUIService啟動之后,調(diào)用SystemUIApplication的startServicesIfNeeded()啟動相應(yīng)的服務(wù)(“Android 12 源碼分析 —— 應(yīng)用層 二(SystemUI大體組織和啟動過程)http://t.csdn.cn/chk6Y”)
  2. 啟動的服務(wù)中,有一個叫做StatusBar,它會在第一步中,被調(diào)用start()方法
  3. 在start()方法中,會調(diào)用createAndAddWindows()方法
  4. createAndAddWindows()方法會調(diào)用makeStatusBarView()方法
  5. makeStatusBarView()方法會找到id為qs_frame的FrameLayout并向其中添加一個QSFragment
  6. QSFragment會去加載qs_panel.xml文件,而這個文件,正是我們的快速設(shè)置的布局文件

qs_panel.xml文件分析

qs_panel.xml原文如下:

<com.android.systemui.qs.QSContainerImpl
    android:id="@+id/quick_settings_container" >

    <com.android.systemui.qs.NonInterceptingScrollView
        android:id="@+id/expanded_qs_scroll_view">
        <com.android.systemui.qs.QSPanel
            android:id="@+id/quick_settings_panel">
            <include layout="@layout/qs_footer_impl" />
        </com.android.systemui.qs.QSPanel>
    </com.android.systemui.qs.NonInterceptingScrollView>

    <include layout="@layout/quick_status_bar_expanded_header" />

    <include android:id="@+id/qs_detail" layout="@layout/qs_detail" />

    <include android:id="@+id/qs_customize" layout="@layout/qs_customize_panel"
        android:visibility="gone" />

</com.android.systemui.qs.QSContainerImpl>
  1. QSContainerImpl:快速設(shè)置的父容器
  2. NonInterceptingScrollView:快速設(shè)置中各個圖標(biāo)的ScrollView
  • QSPanel:QSPanel展示里面具體的詳情
  • qs_footer_impl.xml:快速設(shè)置底部的顯示視圖,如編輯快速設(shè)置的圖標(biāo),見后面圖片的對應(yīng)關(guān)系
  1. quick_status_bar_expanded_header.xml:快速設(shè)置中的頭部區(qū)域,見下面的圖片設(shè)置
  2. qs_detail.xml:快速設(shè)置的詳細(xì)信息
  3. qs_customize.xml:編輯快速設(shè)置的界面

為了能夠方便的對應(yīng)起來,見下面的圖片

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局
在這里插入圖片描述

在上面的圖片中我們可以看到,QSPanel內(nèi)部,將會有有各種各樣的快速設(shè)置的小圖標(biāo),而這些圖標(biāo)被稱為QSTile.

我們將會在QSPanel的源碼分析中,詳細(xì)講解他們的加載過程。本文旨在介紹SystemUI的布局設(shè)計,而非對某個UI的具體細(xì)節(jié)。

介紹完了qs_frame的布局以后,我們還需要查看該window下面的最后一個布局NotificationStackScrollLayout

NotificationStackScrollLayout布局分析

NotificationStackScrollLayout是一個類,它也沒有使用include來引用其他的布局文件,而其內(nèi)部則是通過其他的方式來添加布局的。

NotificationStackScrollLayout加載通知布局的流程
  1. 當(dāng)系統(tǒng)有通知到來時,調(diào)用NotificationListener的onNotificationPosted()方法
  2. 在onNotificationPosted方法中,會通知NotificationEntryManager的mNotifiListener的onNotificationPosted()方法
  3. 在該方法中,會調(diào)用addNotification()方法,然后在addNotification()中調(diào)用addNotificationInternal()方法
  4. 在addNotificationInternal()方法中,會調(diào)用NotificationRowBinderImpl的inflateViews()方法
  5. 在這個方法中,會去調(diào)用RowInFlaterTask的inflate()方法
  6. 在inflate()方法中,會去加載status_bar_notification_row.xml文件

接下來我們看看這個文件的內(nèi)容

status_bar_notification_row.xml文件解析

status_bar_notification_row.xml文件的原文如下:

<com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
    android:id="@+id/expandableNotificationRow">
 <!--只有一個ExpandableNotificationRow-->
</com.android.systemui.statusbar.notification.row.ExpandableNotificationRow>

只有一項內(nèi)容,當(dāng)然其內(nèi)部的內(nèi)容,我們現(xiàn)在不需要關(guān)系,ExpandableNotificationRow是我們觀察的最小布局,因為其內(nèi)部已經(jīng)涉及具體的內(nèi)容該怎么顯示了,現(xiàn)在我們只需要領(lǐng)略大概的布局,并明白相關(guān)的概念

  1. ExpandableNotificationRow:一個可展開的通知

Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念),Android12 SystemUI,SystemUI鎖屏布局,SystemUI狀態(tài)欄布局,SystemUIQS布局,QuickSettings布局,SystemUI通知布局

注意:對于通知的排序,優(yōu)先級等,我們將在后面的文章中,一一介紹,此處只需了解整體布局和基本概念即可

至此,NotificationShade窗口的布局介紹基本已經(jīng)完成,在這里面我們熟悉了各個UI的實體,當(dāng)然也省略了一些UI的實體,
省略的部分,將會在后面文章的子主題中,詳細(xì)介紹。

接下來我們接續(xù)查看剩下的兩個window——StatusBar和NavigationBar

StatusBar(狀態(tài)欄)Window的詳細(xì)布局

StatusBar(狀態(tài)欄)window的加載流程

先簡單介紹其加載流程

  1. SytemUIService啟動之后,調(diào)用SystemUIApplication的startServicesIfNeeded()啟動相應(yīng)的服務(wù)(“Android 12 源碼分析 —— 應(yīng)用層 二(SystemUI大體組織和啟動過程)http://t.csdn.cn/chk6Y”)
  2. 啟動的服務(wù)中,有一個叫做StatusBar,它會在第一步中,被調(diào)用start()方法
  3. 在start()方法中,會調(diào)用createAndAddWindows()方法
  4. createAndAddWindows()方法會調(diào)用makeStatusBarView()方法
  5. makeStatusBarView()方法中,會調(diào)用inflateStatusBarWindow()方法
  6. 在inflateStatusBarWindow()方法中,會通過StatusBarComponent的getStatusBarWindowController()方法得到StatusBarWindowController
  7. 在StatusBarWindowController的構(gòu)造函數(shù)中,會調(diào)用SuperStatusBarViewFactory的getStatusBarWindow()方法
  8. 而SuperStatusBarViewFactory的getStatusBarWindow()方法將會去加載super_status_bar.xml文件
  9. 在第四步的createAndAddWindows()方法中,會調(diào)用StatusBarWindowController的attach()方法,將其添加到屏幕上

接下來看看StatusBar(狀態(tài)欄)的布局文件

StatusBar(狀態(tài)欄)Window的頂層視圖

super_status_bar.xml的源文件如下:

<com.android.systemui.statusbar.phone.StatusBarWindowView>
    <FrameLayout
        android:id="@+id/status_bar_launch_animation_container"/>
    <FrameLayout
        android:id="@+id/status_bar_container" />
</com.android.systemui.statusbar.phone.StatusBarWindowView>

非常,非常的清爽??!

  1. StatusBarWindow:表示了狀態(tài)欄的最頂層視圖
  2. id為status_bar_launch_animation_container的FrameLayout:在這里面顯示動畫,例如:從StatusBar(狀態(tài)欄)中啟動一個Activity時的動畫顯示區(qū)域
  3. id為status_bar_contianer的FrameLayout:這就是現(xiàn)實狀態(tài)欄內(nèi)容的主要區(qū)域

接下來我們查看其詳細(xì)細(xì)節(jié)

StatusBar(狀態(tài)欄)的布局分析

上面id為status_bar_contianer是一個FrameLayout,我們來看看其如何加載布局的。先簡單介紹其布局加載流程

StatusBar(狀態(tài)欄)布局加載流程
  1. SytemUIService啟動之后,調(diào)用SystemUIApplication的startServicesIfNeeded()啟動相應(yīng)的服務(wù)(“Android 12 源碼分析 —— 應(yīng)用層 二(SystemUI大體組織和啟動過程)http://t.csdn.cn/chk6Y”)
  2. 啟動的服務(wù)中,有一個叫做StatusBar,它會在第一步中,被調(diào)用start()方法
  3. 在start()方法中,會調(diào)用createAndAddWindows()方法
  4. createAndAddWindows()方法會調(diào)用makeStatusBarView()方法
  5. makeStatusBarView()方法,會將CollapsedStatusBarFragment放入id為status_bar_container的FrameLayout中
  6. 而CollapsedStatusBarFragment會在其onCreateView的時候,加載并初始化status_bar.xml文件

status_bar.xml文件分析

status_bar.xml文件原文如下:

<com.android.systemui.statusbar.phone.PhoneStatusBarView
    android:id="@+id/status_bar">

    <ImageView
        android:id="@+id/notification_lights_out"/>

    <LinearLayout android:id="@+id/status_bar_contents">
        <FrameLayout>
            <include layout="@layout/heads_up_status_bar_layout" />

            <LinearLayout
                android:id="@+id/status_bar_left_side">
                <ViewStub
                    android:id="@+id/operator_name"/>

                <com.android.systemui.statusbar.policy.Clock
                    android:id="@+id/clock"/>

                <include layout="@layout/ongoing_call_chip" />

                <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
                    android:id="@+id/notification_icon_area"/>

            </LinearLayout>
        </FrameLayout>

        <!-- Space should cover the notch (if it exists) and let other views lay out around it -->
        <android.widget.Space
            android:id="@+id/cutout_space_view" />

        <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
            android:id="@+id/centered_icon_area"/>

        <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/system_icon_area">

            <include layout="@layout/system_icons" />
        </com.android.keyguard.AlphaOptimizedLinearLayout>
    </LinearLayout>

    <ViewStub
        android:id="@+id/emergency_cryptkeeper_text"/>

</com.android.systemui.statusbar.phone.PhoneStatusBarView>
  1. PhoneStatusBarView:狀態(tài)欄內(nèi)容的父容器
  2. 當(dāng)狀態(tài)欄被請求以SYSTEM_UI_FLAG_LOW_PROFILE模式顯示時,這個視圖負(fù)責(zé)顯示一個小點
  3. id為status_bar_content的LinearLayout:顯示狀態(tài)欄內(nèi)容
  • heads_up_status_bar_layout.xml:處在StatusBar中的部分提示信息
  • id為status_bar_left_side的LinearLayout:狀態(tài)欄左邊的顯示區(qū)域
  • Space:填充中間的空白區(qū)域
  • AlphaOptimizedFrameLayout:中心圖標(biāo)顯示區(qū)域
  • AlphaOptimizedLinearLayout:系統(tǒng)圖標(biāo)顯示區(qū)域,如電量百分比
  1. id為emergency_cryptkeeper_text的ViewStub:顯示只能撥打緊急呼救電話

從上面的布局文件可以看到,StatusBar(狀態(tài)欄)大致分成了三個區(qū)域,左,中,右,現(xiàn)在只需要了解其中大體布局即可,即能夠在閱讀源碼的時候,知道源碼中的View指的是哪一部分區(qū)域即可。在后面的文章中,我們將詳細(xì)介紹這些布局的內(nèi)容和實現(xiàn)細(xì)節(jié)。

至此,我們了解了,SystemUI中,最重要的兩個Window的布局。剩下最后一個Window即NavigationBar,因為其布局的簡單,我們將在分析Android導(dǎo)航手勢的時候,一并介紹

本文,只需要掌握如下幾個概念即可,因為后面的系列文章,還會反復(fù)提及:

  1. SystemUI的Window的劃分
  2. SystemUI的各個UI的名字如,NotificationShadeView,QS等等
  3. 知道對應(yīng)的View的Controller的名字,大概會是什么樣子,如NotificationShadeWindowView的Controller,應(yīng)該叫做NotificationShadeWindowViewController,反之亦然

因為最近身體欠佳,加之已經(jīng)開學(xué),學(xué)業(yè)繁重,行文倉促,難免有些錯誤,忘看到的讀者給予提醒,謝謝先。

補(bǔ)充:布局查看工具

讀者可使用下面的工具,進(jìn)行相應(yīng)的布局查看

  1. 老版本DDMS,的hierarchy view
  2. Android Studio的YALI(通過插件市場安裝)
  3. Android Studio的Legacy Layout Inspector(通過插件市場安裝)

至于Android Studio自帶的Layout Inspector就不推薦使用了。文章來源地址http://www.zghlxwxcb.cn/news/detail-719717.html

到了這里,關(guān)于Android 12 源碼分析 —— 應(yīng)用層 四(SystemUI的基本布局設(shè)計及其基本概念)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Android 應(yīng)用層 到 HAL 層

    Android 應(yīng)用層 到 HAL 層

    如下 AOSP軟件堆棧架構(gòu)圖 主要跨兩個階段 Android Apps == Android Framework == HAL ,這種 IPC跨進(jìn)程通信 在 Android 中必須要了解的相關(guān)知識點: 1》 Binder IPC 通信機(jī)制;2》 JNI 調(diào)用;3》 AIDL、HIDL 接口定義語言 1》 Binder IPC 通信機(jī)制 IPC 域 說明 /dev/binder 框架/應(yīng)用進(jìn)程之間的 IPC,使用

    2024年02月10日
    瀏覽(18)
  • 4.1 應(yīng)用層Hook掛鉤原理分析

    4.1 應(yīng)用層Hook掛鉤原理分析

    InlineHook 是一種計算機(jī)安全編程技術(shù),其原理是在計算機(jī)程序執(zhí)行期間進(jìn)行攔截、修改、增強(qiáng)現(xiàn)有函數(shù)功能。它使用鉤子函數(shù)(也可以稱為回調(diào)函數(shù))來截獲程序執(zhí)行的各種事件,并在事件發(fā)生前或后進(jìn)行自定義處理,從而控制或增強(qiáng)程序行為。Hook技術(shù)常被用于系統(tǒng)加速、功

    2024年02月08日
    瀏覽(17)
  • 《計算機(jī)網(wǎng)絡(luò)》實驗八 應(yīng)用層相關(guān)協(xié)議分析

    《計算機(jī)網(wǎng)絡(luò)》實驗八 應(yīng)用層相關(guān)協(xié)議分析

    實驗八 應(yīng)用層相關(guān)協(xié)議分析.............................................................................................. 2 一、實驗?zāi)康?................................................................................................................... 2 二、實驗原理.......................................................................

    2024年02月03日
    瀏覽(20)
  • 根據(jù)源碼,模擬實現(xiàn) RabbitMQ - 網(wǎng)絡(luò)通訊設(shè)計,自定義應(yīng)用層協(xié)議,實現(xiàn) BrokerServer (8)

    根據(jù)源碼,模擬實現(xiàn) RabbitMQ - 網(wǎng)絡(luò)通訊設(shè)計,自定義應(yīng)用層協(xié)議,實現(xiàn) BrokerServer (8)

    目錄 一、網(wǎng)絡(luò)通訊協(xié)議設(shè)計 1.1、交互模型 1.2、自定義應(yīng)用層協(xié)議 1.2.1、請求和響應(yīng)格式約定 ?編輯 1.2.2、參數(shù)說明 1.2.3、具體例子 1.2.4、特殊栗子 1.3、實現(xiàn) BrokerServer 1.3.1、屬性和構(gòu)造 1.3.2、啟動 BrokerServer 1.3.3、停止 BrokerServer 1.3.4、處理每一個客戶端連接 1.3.5、讀取請求

    2024年02月10日
    瀏覽(20)
  • 【音視頻|ALSA】基于alsa-lib開發(fā)ALSA應(yīng)用層程序--附帶源碼

    【音視頻|ALSA】基于alsa-lib開發(fā)ALSA應(yīng)用層程序--附帶源碼

    ??博客主頁??:??https://blog.csdn.net/wkd_007?? ??博客內(nèi)容??:??嵌入式開發(fā)、Linux、C語言、C++、數(shù)據(jù)結(jié)構(gòu)、音視頻?? ??本文內(nèi)容??:??基于alsa-lib開發(fā)ALSA應(yīng)用層程序?? ??金句分享??:??蓋士人讀書,第一要有志,第二要有識,第三要有恒。有志則斷不甘為下流,有

    2024年02月08日
    瀏覽(32)
  • Android 12系統(tǒng)源碼_SystemUI(八)SystemUIVisibility屬性

    在Android系統(tǒng)中,很多應(yīng)用都需要根據(jù)具體情況來控制狀態(tài)欄和導(dǎo)航欄的顯示和隱藏,又或者將狀態(tài)欄透明,實現(xiàn)諸如沉浸式、全面屏燈效果,而要實現(xiàn)這些效果,都離不開SystemUIVisibility屬性。由于SystemUIVisibilityy屬性主要用來控制系統(tǒng)狀態(tài)欄和導(dǎo)航欄的行為,而狀態(tài)欄和導(dǎo)航

    2024年02月06日
    瀏覽(20)
  • 【計算機(jī)網(wǎng)絡(luò)概述】第二章:應(yīng)用層:2.1 應(yīng)用層原理

    【計算機(jī)網(wǎng)絡(luò)概述】第二章:應(yīng)用層:2.1 應(yīng)用層原理

    客戶端/服務(wù)器模式 peer to peer 模式(對等模式) ???????在第一章的內(nèi)容中,我們學(xué)習(xí)了計算機(jī)網(wǎng)絡(luò)的大體輪廓,因為在計算機(jī)網(wǎng)絡(luò)中,我們需要記住非常多的專有名詞,所以在第一章中,我們需要進(jìn)行非常多的記憶。第一章還是非常重要的。 ???????比如,我們所使用

    2024年01月18日
    瀏覽(57)
  • 應(yīng)用層與傳輸層~

    應(yīng)用層與傳輸層~

    應(yīng)用層是負(fù)責(zé)應(yīng)用程序之間溝通的一層。由于不同的網(wǎng)絡(luò)應(yīng)用的應(yīng)用進(jìn)程之間,有著不同的通信規(guī)則,因此自然就需要應(yīng)用層協(xié)議來解決這些問題,這就構(gòu)成了應(yīng)用層的主要內(nèi)容即:精確定義這些通信規(guī)則。 應(yīng)用層有不少應(yīng)用廣泛的協(xié)議,像域名系統(tǒng)(DNS)、文件傳輸協(xié)議(

    2023年04月08日
    瀏覽(20)
  • 應(yīng)用層協(xié)議 HTTP

    應(yīng)用層協(xié)議 HTTP

    我們已經(jīng)學(xué)過 TCP/IP , 已然知道數(shù)據(jù)能從客戶端進(jìn)程經(jīng)過路徑選擇跨網(wǎng)絡(luò)傳送到服務(wù)器端進(jìn)程。 我們還需要知道的是,我們把數(shù)據(jù)從 A 端傳送到 B 端, TCP/IP 解決的是順豐的功能,而兩端還要對數(shù)據(jù)進(jìn)行加工處理或者使用,所以我們還需要一層協(xié)議,不關(guān)心通信細(xì)節(jié),關(guān)心應(yīng)用

    2024年02月06日
    瀏覽(24)
  • 【網(wǎng)絡(luò)】-- 應(yīng)用層

    【網(wǎng)絡(luò)】-- 應(yīng)用層

    目錄 TCP協(xié)議通訊流程 三次握手的過程 四次揮手的過程 TCP 和 UDP 對比 應(yīng)用層 \\\"協(xié)議\\\" 網(wǎng)絡(luò)版計算器 認(rèn)識TCP 守護(hù)進(jìn)程 鋪墊講解 守護(hù)進(jìn)程講解 setsid 總結(jié) ????????下圖是基于TCP 協(xié)議的客戶端 / 服務(wù)器程序的一般流程: TCP是面向連接的通訊協(xié)議,在通訊之前,需要進(jìn)行 3次握

    2023年04月09日
    瀏覽(60)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包