当前位置: 首页 > news >正文

深入探索Symbian活动对象开发

Author:孙东风

Date:04/02/2008

ActiveObject是Symbian中的一个重要概念,它是Symbian OS为了节省系统资源利用单线程来实现多任务异步处理的机制。

S60本身的Framwork也大量采用AO进行多任务的实现,例如我们可以在S60 EIKON Control based application中直接调用以下代码添加自身的AO到系统CActiveScheduler中。

void CActiveTest3NewClass::ConstructL()
{
User::LeaveIfError(iTimer.CreateLocal());// Initialize timer
CActiveScheduler::Add(this);// Add to scheduler
}

如果你有CustKit、DevKit或者BAK,那么跟踪Symbian程序的入口

GLDEF_C TInt E32Main()
{
return EikStart::RunApplication( NewApplication );
}

你会发现EikStart::RunApplication其实调用的就是CActiveScheduler::Start(),这个调用启动了一个CActiveScheduler并进入了CActiveScheduler的循环。而程序一旦进入了CActiveScheduler的循环后就不会跳出来,直到程序结束。

这一点很像Windows的消息循环机制:

while(getMessage(...))

{

TranslateMessage(...);

DispatchMessage(...);

}

CActiveScheduler维护着一个等待循环,这个等待循环用于接受所有活动对象发出的请求,然后交给相应的服务器程序进行处理。当请求得到响应后,服务器会产生一个事件,这个事件由RunL()函数处理,事件处理完后RunL()函数可以决定是继续发送下一个请求还是终止发出请求。

例如下面的程序就是RunL()处理后继续发送请求,从而让程序不断的循环:

void CActiveTest3NewClass::RunL()
{
ShowDialog(iCount++);
SetActive();// Tell scheduler a request is active
}

当然上面这个循环太过于快速,有时候会出现"跳表"。那么可以采用一个RTimer进行时钟控制:

void CActiveTest3NewClass::RunL()
{
ShowDialog(iCount++);

//iTimer.After(iStatus, 1000000); // Set for 1 sec later
SetActive();// Tell scheduler a request is active
}

既然CActiveScheduler负责AO的调度,那么明白CActiveScheduler的调度原则就显得很重要,CActiveScheduler的调度原则分为下面两条:

①根据AO的优先级顺序对已经add进来的AO逐个检查。

CActiveScheduler有一张AO表,按优先级从大到小的顺序记录它所拥有的AO。然后根据每个AO的优先级决定谁先得到服务器的响应。

②判断当前遍历到的AO的IsActive()值和iStatus状态。

在IsActive()为ETrue并且iStatus != KRquestPending时,才会把AO的请求提交给服务器程序。在接收到服务器的响应后,再执行AO的RunL()方法。

其中TRequestStatus iStatus是抽象基类CActive的一个状态变量,它是TRequestStatus类的对象,封装了服务器返回时提供的状态或错误码。当发出请求时,活动对象将iStatus的引用传递到服务器,服务器将iStatus的值设为KRequestPedding而阻塞其它请求。当请求完成时,服务器将iStatus的值设为KErrNone。

下面是我写的一个AO的测试例子,实现了一个动画:

/*
============================================================================
Name : ActiveTest3NewClass.h
Author : DongfengSun
Version : 04/02/2008
Copyright : Your copyright notice
Description : CActiveTest3NewClass declaration
============================================================================
*/

#ifndef ACTIVETEST3NEWCLASS_H
#define ACTIVETEST3NEWCLASS_H

#include <e32base.h>// For CActive, link against: euser.lib
#include <e32std.h>// For RTimer, link against: euser.lib

class CActiveTest3NewClass : public CActive
{
public:
CActiveTest3NewClass();
void ConstructL();
~CActiveTest3NewClass();

public: // New functions
void StartL(TTimeIntervalMicroSeconds32 aDelay);
void ShowDialog(TInt aCount);

private: // From CActive
void RunL();
void DoCancel();

private:
enum TActiveTest3NewClassState
{
EUninitialized,
EInitialized,
EError
};

private:
TInt iState;
RTimeriTimer;
TIntiCount;

};

#endif

/*
============================================================================
Name : ActiveTest3NewClass.cpp
Author : DongfengSun
Version : 04/02/2008
Copyright : Your copyright notice
Description : CActiveTest3NewClass implementation
============================================================================
*/

#include "ActiveTest3NewClass.h"
#include "aknnotewrappers.h"

CActiveTest3NewClass::CActiveTest3NewClass() : CActive(EPriorityStandard)
{
ConstructL();
}

void CActiveTest3NewClass::ConstructL()
{
User::LeaveIfError(iTimer.CreateLocal());
CActiveScheduler::Add(this);
}

CActiveTest3NewClass::~CActiveTest3NewClass()
{
Cancel();
}

void CActiveTest3NewClass::DoCancel()
{
iTimer.Cancel();
}

void CActiveTest3NewClass::StartL(TTimeIntervalMicroSeconds32 aDelay)
{
Cancel();
iState = EUninitialized;
iTimer.After(iStatus, aDelay);
TRAPD(ERROR,SetActive());
TBuf<12> iBuf;
iBuf.AppendNum(ERROR);
CEikonEnv::Static()->InfoMsg(iBuf);
}


void CActiveTest3NewClass::ShowDialog(TInt aCount)
{
TBuf<32> iBuf;
iBuf.operator += _L("The index is :");
iBuf.AppendNum(aCount);
CAknInformationNote* iInfoNote = new (ELeave) CAknInformationNote;
iInfoNote->ExecuteLD(iBuf);
}

void CActiveTest3NewClass::RunL()
{
if (iState == EUninitialized) {
iState = EInitialized;
} else if (iState != EError) {
}
ShowDialog(iCount++);
iTimer.After(iStatus, 1000000);
SetActive();
}

相关文章:

  • 计算机信息技术ppt,计算机信息技术基本.ppt
  • 大话2正在连接登录服务器,大话西游手游服务器连接失败进不去解决办法
  • SqlServer下数据库链接的使用方法
  • outlook邮箱怎么配置服务器地址多少,Outlook如何设置?Outlook设置方法
  • 将SQL Server 2005中的数据同步到Oracle中
  • 服务器日志文件可以自动删除吗,宝塔面板/www/server/total/logs/里面日志文件 删除方法...
  • 热烈庆祝自己的blog的点击量突破5000
  • excel打开时显示只读或服务器没响应而打不开怎么办,Excel打开时显示只读或服务器没响应而打不开怎么办...
  • sql 中OSQL ;DTS;SSIS的批处理写法
  • vue使用什么进行css开发,详解vue-loader在项目中是如何配置的
  • 重新启动sql的批处理文件
  • IIS重新启动
  • 数据库中存储过程的自动化生成
  • SQL SERVER数据库开发之存储过程应用
  • 有关数据库存储过程编写的经验总结
  • Create React App 使用
  • FastReport在线报表设计器工作原理
  • IDEA 插件开发入门教程
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • 工作中总结前端开发流程--vue项目
  • 浏览器缓存机制分析
  • 如何设计一个比特币钱包服务
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 微信小程序实战练习(仿五洲到家微信版)
  • 温故知新之javascript面向对象
  • 找一份好的前端工作,起点很重要
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • Linux权限管理(week1_day5)--技术流ken
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #13 yum、编译安装与sed命令的使用
  • #162 (Div. 2)
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (五)Python 垃圾回收机制
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • .gitignore文件_Git:.gitignore
  • .NET : 在VS2008中计算代码度量值
  • .NET Standard 的管理策略
  • .NET 分布式技术比较
  • .net 验证控件和javaScript的冲突问题
  • .NET程序员迈向卓越的必由之路
  • .net开发时的诡异问题,button的onclick事件无效
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • [100天算法】-每个元音包含偶数次的最长子字符串(day 53)
  • [2023年]-hadoop面试真题(一)
  • [383] 赎金信 js
  • [AIGC] 如何建立和优化你的工作流?