织梦CMS - 轻松建站从此开始!

罗索

symbian中活动对象的一些简单的使用

jackyhwei 发布于 2010-07-10 23:33 点击:次 
Symbian提供了一个活动服务对象的框架,允许把程序里并发执行对象(其实不是并发,不过宏观上看来是)放在一个线程里面执行,这些并发工作的对象就通过活动规划器(ActiveScheduler)来进行管理.
TAG:

Symbian官方推荐使用活动服务对象(CActive)来代替多线程的使用,我想这个道理是很明了的,在手机这样的小内存设备里,运行多线程的程序是非常耗资源的,为了节约资源,symbian提供了一个活动服务对象的框架,允许把程序里并发执行对象(其实不是并发,不过宏观上看来是)放在一个线程里面执行,这些并发工作的对象就通过活动规划器(ActiveScheduler)来进行管理.


关于这两个东西的介绍,网上有一大堆的文档,我就不在这里废话了,如何使用呢?这里我先举一个简单的计数器的例子.我选择写一个exe的程序,也就是说程序是以E32Main为入口的.

  1. GLDEF_C TInt E32Main() 
  2.  CTrapCleanup* cleanup=CTrapCleanup::New(); 
  3.  TRAPD(error,callInstanceL()); 
  4.  if (error != KErrNone){ 
  5.  printf("get error %d\r\n", error); 
  6.  } 
  7.  delete cleanup; 
  8.  return 0; 

以上的内容是每一个exe文件都应该做的,CTrapCleanup* cleanup=CTrapCleanup::New()建立一个清除堆栈,以便程序在异常退出的时候把清除堆栈里面的资源都释放掉.当然你也可以加上堆检测宏,这里我就不多说了.TRAPD是symbian里面经常使用的宏,功能类似于try,第一个参数是让定义一个错误返回值变量的名字, 后面就是可能有异常的你写的函数.当这个函数异常时,程序不会crash, 你可以得到异常的原因.可以参考nokia论坛上的一些关于这些使用的文档.
接下来是vcallInstanceL函数,在这个函数里面我来建立ActiveScheduler.

  1. LOCAL_C void callInstanceL() 
  2.  CActiveScheduler* scheduler = new(ELeave) CActiveScheduler(); 
  3.  CleanupStack::PushL(scheduler); 
  4.  CActiveScheduler::Install(scheduler); 
  5.  TRAPD(error,doInstanceL()); 
  6.  if(error) { 
  7.  printf("error code=%d\r\n",error); 
  8.  } 
  9.  else { 
  10.  printf("OK!\r\n[press any key]"); 
  11.  } 
  12.  CleanupStack::PopAndDestroy(scheduler); 

这段程序很简单就是创建一个活动规划器,并压入清除栈,然后安装活动规划器,这样就可以用了.再执行真正的实例函数,最后出栈销毁.doinstanceL我们放到最后来写,现在来构造我们的活动计数器对象.

  1. class TimeCount : public CActive 
  2. public : 
  3.  static TimeCount* NewLC(); // 构造函数 
  4.  ~TimeCount(); 
  5.  void StartL(); // 计数开始 
  6.  void ConstructL(); 
  7.  void RunL(); // 延时事件到达以后的处理函数 
  8.  void DoCancel(); // 取消请求提交 
  9.  void setDelayTime(int delayTime); 
  10. private
  11.  TimeCount(); 
  12.  RTimer iTimer; // 定时器 
  13.  int iTimeCount; // 计数器 
  14.  int mTime; // 计数间隔时间 单位秒 
  15. }; 
  16. TimeCount::TimeCount() 
  17. : CActive(0) // 这里可以设置活动对象的优先级 
  18.  // 把自己加入活动规划器 
  19.  CActiveScheduler::Add(this); 
  20. TimeCount* TimeCount::NewLC() 
  21.  TimeCount* result = new (ELeave) TimeCount(); 
  22.  CleanupStack::PushL( result ); 
  23.  result->ConstructL(); 
  24.  return result; 
  25. void TimeCount::DoCancel(void
  26.  iTimer.Cancel(); 
  27. void TimeCount::setDelayTime(int mTime) 
  28.  DelayTime = mTime; 
  29. TimeCount::~TimeCount() 
  30.  Cancel(); 
  31.  iTimer.Close(); 
  32. void TimeCount::StartL() 
  33.  // 设定定时器状态为每隔mTime秒钟状态完成一次 
  34.  iTimer.After(iStatus, 10000 * 100 * mTime); 
  35.  // 提交异步请求 
  36.  SetActive(); 
  37. void TimeCount::ConstructL() 
  38.  // 初始化计数器和定时器 
  39.  iTimeCount = 0; 
  40.  User::LeaveIfError(iTimer.CreateLocal()); 
  41. void TimeCount::RunL() 
  42.  // 计数器+1以后继续提交延时请求事件 
  43.  printf("The Count is ->>%d", iTimeCount++); 
  44.  StartL(); 

每一个活动服务对象都有一个iStatus来标识当前对象的状态.在这里我们把iStatus设定为iTimer.After(iStatus, 10000 * 100 * mTime);也就是定时器定时mTime秒钟以后iStatus发生改变,这个时候活动规划器会收到这个状态的改变,从而调用相应活动对象的处理函数,也就是RunL函数.在RunL函数里面进行计数和输出,然后调用startL重新设置定时器和对象状态,再提交给活动规划器.这样mTime秒钟以后活动规划器会再次调用RunL函数.一直这样重复,这样就达到了计数器的效果.
最后我们来写doinstanceL函数

  1. LOCAL_C void doInstanceL() 
  2.  TimeCount* timeCount = TimeCount::NewLC(); 
  3.  // 每隔一秒钟打印一次 
  4.  TimeCount->setDelayTime(1); 
  5.  TimeCount->StartL(); 
  6.  CActiveScheduler::Start(); 
  7.  CleanupStack::PopAndDestroy(1); 

创建好对象以后,加上CActiveScheduler::Start()程序就开始运行了,这句话告诉活动规划器该等待对象的状态的改变了,在这里就是timeCount的iStatus的改变.等iStatus改变并调用了RunL以后,继续等待iStstus的改变,这样我们使用活动对象的计数器就能够通过消息驱动运行起来了.
这里的CActiveScheduler只管理了一个CActive对象,就是timeCount,可以用类似的方法实现多个CActive,并且都加入CActiveScheduler,CActiveScheduler将会等待所有加入它的CActive的状态的改变,其中有一个的状态改变就会去执行对应的活动对象的处理函数,当状态同时发生的时候,会通过对象的优先级来决定先调用谁的RunL函数.CActiveScheduler也是非抢占式的,当一个RunL函数还没有执行完的时候,如果另一个CActive的状态改变,会等待RunL执行完以后再执行另一个CActive的处理函数.

From:

http://blog.csdn.net/wistaria2002/archive/2008/07/23/2696920.aspx (wistaria2002)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201007/9807.html]
本文出处:百度博客 作者:wistaria2002
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容