前言
应用程序通过 Notification.Builder 构建通知 (Notification) 对象, 并传递给 NotificationManager 的 notify() 方法。NotificationManager.notify() 方法最终会通过 Binder IPC 调用 NotificationManagerService。
NotificationManagerService 是处理所有通知相关操作的后台服务。NotificationManagerService 接收到通知请求后,会首先构造一个 StatusBarNotification 对象来封装这个通知的详细对象。StatusBarNotification 包含了与通知相关的一些元数据,如通知的 ID、标签、包名以及通知的发布时间等,还包括一个 Notification 对象,这个 Notification 对象正是上述应用程序通过 Notification.Builder 构建的。
当 NotificationManagerService 准备将通知发送给状态栏或其他组件(例如锁屏、穿戴设备等)进行显示时,它会触发相应的回调,如 NotificationListenerService.onNotificationPosted(), 并将包含通知信息的 StatusBarNotification 实例作为参数传递。这样,相关的组件就可以提取 StatusBarNotification 中的 Notification 对象,并根据其中定义的内容和样式来展示通知。
->NotificationManager.notify()
–->NotificationManager.notifyAsUser()
-—->NotificationManagerService.enqueueNotificationWithTag()
---->NotificationManagerService.enqueueNotificationInternal()
----->NotificationManagerService.EnqueueNotificationRunnable()
------>NotificationManagerService.PostNotificationRunnable()
------->NotificationManagerService.notifyPostedLocked()
-------->NotificationManagerService.notifyPosted()
--------->INotificationListener.onNotificationPosted()
---------->NotificationListenerService.onNotificationPosted()
下面是应用程序构建通知的demo, Android 8.0或以上引入了通知渠道,在构建通知前,要先创建通知渠道,否则会报错。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
createNotificationChannel();
AtomicInteger notificationId = new AtomicInteger(0);
binding.btnCreateNotification.setOnClickListener(v -> {
Log.d(TAG, "--> click ");
sendNotification(notificationId.incrementAndGet());
});
}
private void createNotificationChannel() {
Log.d(TAG, "--> createNotificationChannel: ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name); // 渠道名
String description = getString(R.string.channel_description); // 渠道描述
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("MY_CHANNEL_ID", name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Log.d(TAG, "--> notificationManager.createNotificationChannel(channel) ");
}
}
private void sendNotification(int notificationId) {
Log.d(TAG, "--> sendNotification, notificationId: " + notificationId);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "MY_CHANNEL_ID")
.setSmallIcon(R.drawable.ic_notification) // 设置通知图标
.setContentTitle("My Notification Title") // 设置通知标题
.setContentText("This is the notification content. notificationId: "+ notificationId) // 设置通知内容
.setPriority(NotificationCompat.PRIORITY_DEFAULT); // 设置通知的优先级
notificationManager.notify(notificationId, builder.build()); // 发送通知
Log.d(TAG, "--> notificationManager.notify(notificationId, builder.build());");
}
}
网友评论