天天看点

Android 9.0 SystemUI Notification

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

Android 9.0 SystemUI Notification

在《android 9.0 systemui 主要视图 systembars》知道通知在折叠时状态栏、下拉状态栏、锁屏都有通知,其中锁屏和下拉状态栏是一个布局,折叠状态栏 是在 <code>collapsedstatusbarfragment,status_bar.xml,phonestatusbarview</code>,锁屏是 <code>notificationstackscrolllayout,@+id/notification_stack_scroller</code>,先来看看锁屏的通知,notificationstackscrolllayout 是 viewgroup,如果来了条通知,肯定是有地方进行 addview,我们就沿着这个思路去 aosp 寻找答案。

Android 9.0 SystemUI Notification

序列图为来通知到 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 的通知关联起来了,这样,锁屏来通知分析结束。

Android 9.0 SystemUI Notification

有了以上锁屏通知分析,再来分析折叠状态栏通知就简单很多了,先看来折叠状态栏初始化部分。

折叠状态栏对应的布局文件是 status_bar.xml:

如果来通知,就在 notification_icon_area 进行 addview 填充。再看看代码初始化。

看到这里的<code>notificationiconarea.addview(mnotificationiconareainner);</code> ,notificationiconarea 被 mnotificationiconareainner 填充,因此我们要重点关注 notificationiconareacontroller 什么时候被填充。

有以上锁屏通知分析知道有通知来最后会调用 statusbar#updatenotificationviews。

调用 notificationiconareacontroller#updatenotificationicons。

ok,折叠状态栏通知分析结束。

本篇梳理了 systemui notification 大致流程,分为锁屏的通知和状态栏通知,代码很多,细节没有去纠结,省略了很多代码,有兴趣,可以自己去 aosp 查看。