用DBUS实现Startup notification的构想
用DBUS实现Startup notification的构想
转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd
作者联系方式:李先静<xianjimli at hotmail dot com>
更新时间:2007-5-11
有的应用程序起动过程比较长,在起动之后,一定时间内没有反应。为了避免让用户等得不耐烦,或者误以为死机了。在此期间,提供一个动画或者其它东西来标识正在起动的状态,可能会更友好一些。Startup notification的初衷也在于此,它跟踪应用程序的起动过程,以便给用户提供一些反馈信息。
当然,Startup notification并不限于应用程序的起动过程,它也适用于打开窗口,或者其它长时间的操作。我们这里讨论的Startup notification有两层含义:
1. Startup notification协议。该协议由freedesktop(http://standards.freedesktop.org)制定,它基于X Windows的客户端消息(ClientMessage)机制,因此消息可以跨进程传递,而无需要额外的IPC机制。在协议中,它定义了消息的类型、参数、使用上下文和其它一些注意事项。
2. Startup notification库。Startup notification协议是基于X Windows消息来定义的,使用不太方便,而且只限于X Window环境,不具有可移植性。freedesktop同时提供了该协议的一种实现,该实现抽象出了定义良好的接口,使用者无需关心里面的实现,所以很容易移植到非X Window的环境。
最初我对Startup notification没有多大兴趣,原因之一是因为,我们的GUI是基于DirectFB而非X Window,不能直接使用freedesktop提供的库,如果使用Startup notification,就得要自己去实现。我不喜欢把事情搞得复杂化,所以当时就没有考虑这个问题。直到最近遇到几个麻烦:
1. 后台服务起动的依赖关系。我们有多个后台服务进程,放在一个起动脚本里起动,服务之间有严格的依赖关系,被依赖的服务可能还没有初始化完成,已经有客户端向它请求服务了,此时请求必定会失败,继而引发一些其它问题。
2. 应用程序起动过程较长。等待时间过长,用户往往以为死机了,或者没有点中,然后狂击屏幕,结果造成多次起动,让系统变得更慢。
3. 其它长时间操作,用户等得烦躁。有时打开某个窗口,或者保存文件,或者其它长时间操作,如果没有提示,用户就会等得着急。
由于我们的GUI是基于DirectFB的,不能使用X Windows的消息机制,自然无法从根本上兼容Startup notification协议,也不能直接使用freedesktop实现的库。看了一下freedesktop实现的Startup notification,它分为三个部分:
1. sn-launcher.h定义了起动者的接口。sn_launcher_context_initiate用来标识起动的开始,sn_launcher_context_complete用来标识起动的结束。至于为什么起动者可以调用sn_launcher_context_complete来标识起动结束,我想可能是因为起动可能会失败,如果失败被起动者根本没有机会发出起动结束的的消息,为了配对,此时起动者可以发出一个结束消息。
2. sn-launchee.h定义了被起动者的接口。sn_launchee_context_complete用来标识起动的结束。被起动者起动后,它进入正常状态了,就可以调用sn_launchee_context_complete告诉所有关注者:自己准备好了。
3. sn-monitor.h定义了监听者的接口。任何关注起动过程的程序都可以调用这套接口去监听起动过程,监听者可以是起动者,也可以是被起动者,也可以是第三方程序,所以这部分功能独立实现是合理的。
在研究之后,我们发现完全可以独立于X Window来实现兼容这套接口的库,尽管可以通过DirectFB的进程间通信机制去分发消息,但考虑到一些后台服务都是与界面无关的,为了避免与GUI的耦合,最终决定用DBUS而非DirectFB作为通信机制。
我们实现了一个名为AppManager的服务,它负责起动其它服务和应用程序,并作为Startup notification消息的中转站。在它提供的消息转发接口上,包装出Startup notification的接口,这套接口兼容freedesktop实现的Startup notification的接口,以保证其它应用程序可以方便的移植到我们平台上来。
有了Startup notification,前面三个问题就迎刃而解了:
1. 后台服务起动的依赖关系。AppManager负责起动所有的服务,对于有依赖要求的服务,在收到起动完成的消息之后,才起动下一个服务。
2. 应用程序起动过程较长。在起动过程中给出动画提示,以缓解用户着急的心态; 忽略此期间的点击消息,以避免重复起动。
3. 其它长时间操作,用户等得烦躁。这可以在状态栏上显示状态动画,笔点移动到上面时,还可以给出提示。
给用户的状态提示是在一个地方完成,我们把它实现成一个桌面项,挂在状态栏里,它监听所有Startup notification事件,并在适当的时候给出状态提示。起动者和被起动者,只需要触发事件,而不关心事件处理,即简单化了实现,也隔离了用户界面和内部逻辑。
~~end~~
参考资源:
1. http://www.freedesktop.org/software/startup-notification/releases/startup-notification-0.8.tar.gz
2. http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt