本文主要分享 systemui notification 具體如何呈現的?基于 aosp 9.0 分析。

在《android 9.0 systemui 主要視圖 systembars》知道通知在折疊時狀态欄、下拉狀态欄、鎖屏都有通知,其中鎖屏和下拉狀态欄是一個布局,折疊狀态欄 是在 <code>collapsedstatusbarfragment,status_bar.xml,phonestatusbarview</code>,鎖屏是 <code>notificationstackscrolllayout,@+id/notification_stack_scroller</code>,先來看看鎖屏的通知,notificationstackscrolllayout 是 viewgroup,如果來了條通知,肯定是有地方進行 addview,我們就沿着這個思路去 aosp 尋找答案。
序列圖為來通知到 systemui 鎖屏通知呈現整個流程。
鎖屏是 notificationstackscrolllayout,直接找 notificationstackscrolllayout,看到有個 addcontainerview方法,一看,果然是目标 addview:
反查,看到 addcontainerview 被 notificationviewhierarchymanager#updatenotificationviews 方法調用了。
這裡 mlistcontainer 是 notificationlistcontainer,notificationstackscrolllayout#addcontainerview 進行了重寫。
反查, notificationviewhierarchymanager#updatenotificationviews 被 statusbar#updatenotificationviews 方法調用了。
statusbar#updatenotificationviews 被 notificationentrymanager#updatenotifications 調用了。
presenter 是 notificationpresenter 對象,從 statusbar#makestatusbarview 傳過來了,繼續看 notificationentrymanager#updatenotifications 哪裡被調用了,是 notificationentrymanager#addnotificationviews。
notificationentrymanager#addentry 由 notificationentrymanager#onasyncinflationfinished 調用了。
問題來了,notificationentrymanager#onasyncinflationfinished 哪裡被調到了,似乎斷掉了,是怎麼和來通知關聯起來的?這得需要看看通知的流程。
這部分分析按照正常的調用順序來分析。
notificationmanager 調用 notify 方法發送 notification,最後調用到 notifyasuser() 方法:
這裡 service 是 inotificationmanager,對應的是 notificationmanagerservice,看 notificationmanagerservice#enqueuenotificationwithtag,又調用了 notificationmanagerservice#enqueuenotificationinternal。
mlisteners 是 notificationlisteners,調用 notificationmanagerservice#notifypostedlocked。
這裡 service 是 inotificationlistener,對應的是 notificationlistenerwrapper,看 notificationlistenerwrapper#onnotificationposted。
看 myhandler 進行中的 msg_on_notification_posted。
notificationlistenerservice 是抽象類,notificationlistenerservice#onnotificationposted 在 notificationlistener##onnotificationposted 有重寫。
調用了 notificationentrymanager#addnotification。
從 notificationentrymanager#addnotification 到 notificationentrymanager#addnotificationinternal 再到 notificationentrymanager#inflateviews 方法。
再看 rowinflatertask#oninflatefinished:
看 notificationentrymanager#row 會調用 bindrow 和 updatenotification,看 updatenotification方法最終會調用 expandablenotificationrow#updatenotification。
繼續跟,到 notificationinflater#inflatenotificationviews。
看 asyncinflationtask 執行的結果:
調用 notificationinflater#apply,最終會到 notificationinflater#applyremoteview
繼續看 notificationinflater#finishifdone,這個方法看到最後的<code>endlistener.onasyncinflationfinished(row.getentry());</code> 實作方法在 notificationentrymanager#onasyncinflationfinished。
這裡的 addentry 方法調用了addnotificationviews,好了,終于和 systemui 的通知關聯起來了,這樣,鎖屏來通知分析結束。
有了以上鎖屏通知分析,再來分析折疊狀态欄通知就簡單很多了,先看來折疊狀态欄初始化部分。
折疊狀态欄對應的布局檔案是 status_bar.xml:
如果來通知,就在 notification_icon_area 進行 addview 填充。再看看代碼初始化。
看到這裡的<code>notificationiconarea.addview(mnotificationiconareainner);</code> ,notificationiconarea 被 mnotificationiconareainner 填充,是以我們要重點關注 notificationiconareacontroller 什麼時候被填充。
有以上鎖屏通知分析知道有通知來最後會調用 statusbar#updatenotificationviews。
調用 notificationiconareacontroller#updatenotificationicons。
ok,折疊狀态欄通知分析結束。
本篇梳理了 systemui notification 大緻流程,分為鎖屏的通知和狀态欄通知,代碼很多,細節沒有去糾結,省略了很多代碼,有興趣,可以自己去 aosp 檢視。