SystemUI通知流程

前言

在上篇文章中,我们已经大概了解了SystemUI的启动流程及结构框架,本文将从Android 15源码层面研究通知相关的发送和显示逻辑。


通知整体交互

一条通知发出要经过三个进程:APP进程、SystemServer进程和SystemUI进程,APP进程发出通知、SystemServer进程统一存储并通知注册的NotificationListenerService,SystemUI显示通知并处理通知事件。

一、通知的发送逻辑

一般来说,如果 app 想发送一条新的通知,都会使用到以下代码

val skipIntent = Intent(context, ResultActivity::class.java)
val clickPendingIntent = PendingIntent.getActivity(context, 0, skipIntent, PendingIntent.FLAG_MUTABLE)
val action = NotificationCompat.Action.Builder(null, "动作", clickPendingIntent).build()
val notificationCompat = NotificationCompat.Builder(context, PUSH_CHANNEL)
      .setSmallIcon(R.drawable.small_icon)
      .setContentTitle("标题")
      .setContentText("内容")
      .setPriority(NotificationCompat.PRIORITY_HIGH)
      .setWhen(System.currentTimeMillis())
      .addAction(action)
NotificationManagerCompat.from(context).notify(123, notificationCompat.build())

可以看到我们通过 NotificationCompat.Builder 新建了一个 Notification 对象,最后通过 NotificationManagerCompat#notify() 方法将 Notification 发送出去。

具体在内部是怎么实现的?

大概流程如下:
在这里插入图片描述

大体上经历下面几个步骤:

  1. 当一个APP要发出通知,会调用NotificationManagerCompat.notify(),并带上APP进程的信息。
  2. APP要把通知发送到SystemServer进程,需要跨进程,首先获取NotificationManagerService的代理,跨进程调用NotificationManagerService的方法。
  3. 进入NotificationManagerService,先把通知加入到通知队列,然后遍历注册到NotificationManagerService中的NotificationListenerService,把通知分发给NotificationListenerService。
  4. SystemUI收到通知后对通知进行后续处理,比如数据过滤筛选。
  5. SystemUI在数据处理完成后,通过调用SystemServer进程创建RemoteViews然后回调给SystemUI对视图进行加载。


二、通知的显示逻辑

SystemUI在启动的时候会注册NotificationListener,后续监听到通知后,经过一系列中转和数据筛选把通知显示出来。

主要时序图如下:
在这里插入图片描述
主要流程包括以下几步:

  1. SystemUI在启动CentralSurfacesImpl服务的时候通过Dagger进行注册NotificationListenerService,所以收到通知消息后会直接回调到NotificationListener。
  2. NotificationListener获取到通知后,会将通知分发给NotificationHandler,再经过NotifCollection的一系列中转并封装成NotificationEntry,最后通过onBuildList回调给ShadeListBuilder。
  3. ShadeListBuilder在收到回调后,对通知进行筛选、过滤、排序、分组等操作最后生成一个新的通知列表。
  4. 新的通知列表通过NotifViewRenderer接口分发给ShadeViewDiffer对View进行操作,如add、remove等。


三、小结

本文从总体上介绍了通知的发送和显示逻辑,旨在对整体框架有一个理解。

如果对某个流程感兴趣也可在评论区留言,后续将针对进行文章分析。

SystemUI通知涉及多个进程,一条通知发出要经过APP进程、SystemServer进程和SystemUI进程。APP进程负责发出通知,SystemServer进程统一存储并通知注册的NotificationListenerService,SystemUI则负责显示通知并处理通知事件 [^1]。 在存储方面,所有的通知信息保存在自定义view NotificationStackScrollLayout中,每个通知被封装进ExpandableNotificationRow,其中主要保存信息内容的对象是NotificationContentView [^3]。 关于Android SystemUI中下拉通知面板时所看到的开关面板(即QS面板),其实现原理涵盖整体架构、UI构建流程与事件处理流程等 [^2]。 使用SystemUI通知时,开发者在APP进程中创建并发出通知,之后系统会按照既定流程SystemUI显示。不过,在不同的Android系统版本中,具体的使用方法和API可能存在差异。以下是一个简单的Android通知发送示例代码: ```java import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.os.Build; public class NotificationUtils { public static void sendNotification(Context context, String title, String content) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); } Notification.Builder builder; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { builder = new Notification.Builder(context, "channel_id"); } else { builder = new Notification.Builder(context); } builder.setContentTitle(title) .setContentText(content) .setSmallIcon(android.R.drawable.ic_dialog_info); Notification notification = builder.build(); notificationManager.notify(1, notification); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值