本文主要分享 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 查看。