13.4 Android的全局通知机制

在应用开发中,往往需要跳脱主要的用户交互界面,向用户提示一些信息。比如,提示用户收到新邮件,提示用户再按一次返回键可以退出应用,通知用户设备正在播放的音乐信息,等等。为了以统一的体验和全局的调度来实现这样的提醒,Android提供了一套实现消息通知的框架,帮助开发者在应用中快速地实现。

13.4.1 全局通知的类型和实现

Android的提醒主要有两种形态(如图13-6所示)。一种称为Toast(实在是无法找到一个合适的中文译名,其英文名也许是因为提醒界面如面包片从面包机中跳出因而得名,一个意译的中文名是“弹出式通知”),是一个临时弹出的通知界面,它不会阻塞用户正在进行的交互,仅会在界面上停留一段时间后自动消失。Toast常用来提供一些反馈信息,这些信息对当前的操作可能有用,但不会阻止用户的交互行为。比如,在很多应用中会使用按两下返回键退出应用的模式(这种设计被认为可以防止用户不理解回退键的作用而导致误退出应用),当用户点击了一次回退键后弹出Toast通知,告知用户可以继续按回退键退出应用。对于新用户而言,弹出的Toast提示信息可以对他后续的操作有所帮助,而对于老用户而言,非阻塞的Toast通知,不会阻止他快速按两次退出键退出应用(想象一下,如果应用选择弹出阻塞的提醒对话框,每次询问用户是否退出,会让老用户多么痛苦)。

另一种全局通知的方式,称之为状态栏通知(Status Bar Notification)。之所以称为状态栏通知,是因为所有的通知项都可以以图标的形式显示在状态栏上,用户可以在通知栏上通过下拉操作,看到一份完整的状态栏通知列表,其中包含了各个状态栏通知的具体内容,并可以与之做一定的交互。当用户点击列表中的通知项时,会触发一些预设的事件。比如,邮件应用可以在收取到新邮件时通过状态栏通知来提示用户,当用户点击该通知项时,可以通过预设的事件,触发弹出邮件界面组件来呈现具体的新邮件内容。

不论是Toast还是状态栏通知,都是基于全局的。所谓基于全局,就是所有的通知项都由Android系统来统一调度,控制其生命周期和呈现样式。如图13-7所示,Android有一个通知服务NotificationManagerService,它运行在核心进程的独立线程中,当开发者发出一个Toast通知,会加入到通知服务的Toast队列当中,每个在队列中的Toast通知,都会按照先后次序逐一呈现,每个Toast通知可以预设其呈现时间,到时候通知自动消失,队列中的下一个通知紧接着会被呈现。

状态栏通知同样也是由通知服务统一调度的,当状态栏通知被提交到通知服务中后,通知服务会在已有的状态栏通知列表中查询是否存在与新提交的通知具有相同标识的通知项,进而进行更新、替换,或者新建。状态栏通知的列表是由独立的应用来进行维护的,并不需要通知发出的应用进程来处理,这也体现了其全局性的特征。

13.4 Android的全局通知机制 - 图1

图 13-6 Android各个全局通知的样式

13.4 Android的全局通知机制 - 图2

图 13-7 Android全局通知的处理流程