activeobject 在symbian里是一个很重要的概念
应该说所有的symbian程序都是运行在一个或多个activeobject里面。
大多数symbian的程序的入口几乎都是这样的,除了少数console程序以外
gldef_c tint e32main()
{
return eikstart::runapplication( newapplication );
}
如果你有机会调试并跟踪到symbian的源代码里面,你会发现eikstart::runapplication会调用
cactivescheduler::start()
这个调用意味着启动了一个 scheduler 也就意味着进入了 activescheduler的循环。
程序运行进入cactivescheduler::start()之后就不会出来了,直到程序结束。
这似乎很象什么?对了,象windows的消息循环!
while(getmessage(...))
{
translatemessage(...);
dispatchmessage(...);
}
除非程序退出,否则会一直运行在这样的死循环里面。
scheduler::start里面也是类似的代码,做着类似的事情
1。等待事件
2。找一个合适的对象来处理事件
3。然后继续等待事件,直到得到一个退出的事件。
但是和windows的消息循环不一样的地方在于,scheduler 里面调度的不是窗口
而是一个个activeobject,scheduler获得了一个事件后,就会找一个合适的activeobject去处理事件
所有的activeobject在创建后会通过cactivescheduler::add 把自己加入到scheduler里面。
这套模式又使我想起了什么,对了,是ace--那个网络程序的framework,ace中也是类似的模式
不过scheduler叫做reactor。
不过activeobject叫做task。
本质上讲,这就是一套用单线程通过事件驱动,来模拟多任务的设计模式。
每个activeobject是独立的,多个activeoject看似是并行的,实际上却是运行在一个线程里。
不同的是ace里面的 reactor 是可以多线程的,可以用一个线程池来同时执行多个 task。
在symbian的世界里,设备的资源都很有限,内存小,cpu也慢,所以开一个线程开销比较大,activeobject有效的
代替了部分多线程的功能。
编写activeobject还是比较简单的,所有的activeobject都是从cactive派生的。
其中runl、docancel 是必须重载的虚函数,每次有事件发生scheduler就会调用runl
那么如果有多个activeobject存在,那么事件发生了scheduler怎么才能知道该调用哪个activeobject呢?
很简单,每个activeobject都有一个istatus成员,每个事件发生器都会指定一个istatus,scheduler会调用
istatus对应的那个activeobject。
比如最简单事件发生器,rtimer,他的作用是在指定的时间后产生一个事件,起到定时器的作用
用法如下
rtimer t;
t.after(istatus, 1000000);
上面的语句表示在1秒钟后 产生事件,这个事件将由istatus对应的activeobject来响应。(">symbian系统下 时间单位是 1/1000000 秒,而不是1/1000秒)
![]()
如果喜欢理解 activeobject - symbian请收藏或告诉您的好朋友.
阅读(150) | 评论(0) | 转发(0) |