Symbian中使用活动对象的三种典型设计
来源:百度文库 编辑:神马文学网 时间:2024/04/28 20:40:59
Symbian中使用活动对象的三种典型设计
发表时间:2008-12-18 2:12:59 浏览次数:214
Symbian中活动对象的使用是很频繁的(活动对象的理论我不多说了,关心的朋友自己去查资料,跟Windows平台中的ActiveX对象一个样,对事件的驱动和处理过程也跟它一样,或者说,举个简单的例子,跟Ajax的异步传输一样.因为Symbian的活动对象本来就是用于异步请求的事件处理的).使用活动对象的典型方式我认为有三个: 1.状态机(通俗的说就是在同一线程同一活动对象中处理多步骤的异步请求)class CServiceProvider : public CBase {
public:
static CServiceProvider * NewL();
~CServiceProvider() {};
public:
void GetData(const TDesC& aSource, HBufC8 * aData, TRequestStatus & aStatus);
void CancelGetData();
TInt TranslateData(TDes8 & aData);
void SendData(const TDesC & aTarget, const TDesC8 & aData, TRequestStatus & aStatus);
void CancelSendData();
protected:
CServiceProvider() {};
};void CServiceProvider :: GetData(const TDesC & aSource, HBufC8 * aData, TRequestStatus & aStatus) {
aStatus = KRequestPending;
// 用RFile::Read()的异步重载形式从aSource中获取数据,并写入aData(如果必要,对其
// 重新分配空间),当读取完成,则由文件服务器将aStatus标为完成状态
}void CServiceProvider :: CancelGetData() {...}void CServiceProvider :: TranslateData(TDes8 & aData) {
// 同步解析数据并写入同一个描述符中
...
return translationResult;
}void CServiceProvider :: SendData(const TDesC & aTarget, const TDesC8 & aData, TRequestStatus & aStatus) {
aStatus = KRequestPending;
// 用RFile::Write()的异步重载形式向aTarget中写入数据,该函数在完成时设置aStatus状态
...
}void CServiceProvider :: CancelSendData() {...}const TInt KStandardDataLen = 1024;class CStateMachine : public CActive {
public:
~CStateMachine();
state CStateMachine * NewLC();
void SendTranslatedDate(const TDesC & aSource, const TDesC & aTarget, TRequestStatus &);
protected:
enum TState {EIdle, EGet, ETranslate, ESend};
protected:
CStateMachine();
void InitializeL(const TDesC & aTarget);
void Cleanup();
protected:
virtual void DoCancel();
virtual void RunL();
// RunError()我没有实现,因为RunL()在这个例子中不会Leave,但是这个声明是必须的(受C++语法限制)
virtual TInt RunError(TInt aError);
private:
CServiceProvider * iService;
TState iState;
private:
HBufC * iTarget;
HBufC8 * iStorage;
TRequestStatus * iClientStatus;
};CStateMachine :: CStateMachine() : CActive(EPriorityStandard) {
CActiveScheduler :: Add(this);
}CStateMachine :: ~CStateMachine() {
Cancel();
Cleanup();
}void CStateMachine :: InitializeL(const TDesC & aTarget) {
// 将其保存起来,后面传递给CServiceProvider
iTarget = aTarget.AllocL();
// 保存接收到的数据
iStorage = HBufC8::NewL(KStandardDataLen);
}void CStateMachine :: Cleanup() {
iState = EIdle;
delete iTarget;
iTarget = NULL;
delete iStorage;
iStorage = NULL;
}void CStateMachine :: SendTranslatedData(const TDesC & aSource, const TDesC & aTarget, TRequestStatus & aStatus) {
__ASSERT_ALWAYS(!IsActive, User::Panic(KExPanic, KErrInUse));
ASSERT(EIdle == iState);
iClientStatus = &aStatus;
*iClientStatus = KRequestPending;
TRAPD(r, InitializeL(aTarget));
if(KErrNone != r) {
Cleanup();
User::RequestComplete(iClientStatus, r);
} else {
iService -> GetData(aSource, iStorage, iStatus);
iState = EGet;
SetActive();
}
}void CStateMachine :: RunL() {
ASSERT(EIdle != iState);
if(KErrNone != iStatus.Int()) {
User :: RequestComplete(iClientStatus, iStatus.Int());
Cleanup();
} else {
if(EGet == iState) {
TPtr8 ptr(iStroage.Des());
iService -> TranslateData(ptr);
iState = ETranslate;
TRequestStatus * stat = &iStatus;
User::RequestComplete(stat, r);
SetActive();
} else if(ETranslate == iState) {
TInt r = iService -> SendData(*iTarget, *iStorage, iStatus);
iState = ESend;
SetActive();
} else {
ASSERT(ESend == iState);
User :: RequestComplete(iClientStatus, iStatus.Int());
Cleanup();
}
}
}void CStateMachine :: DoCancel() {
if(iService) {
if(CStateMachine :: EGet == iState) {
iService -> CancelGetData();
} else if(CStateMachine :: ESend == iState) {
iService -> CancelSendData();
}
}
if(iClientStatus) {
User :: RequestComplete(iClientStatus, KErrCancel);
}
} 2.长线任务(通俗的说,也就是在一个优先级低的活动对象中持续处理一个分成很多步的任务,这些任务可以不是异步的,每个步骤之间是自驱动或者叫自完成的)class CLongRunningCalculation : pulbic CBase {
public:
static CLongRunningCalculation * NewL();
TBool StartTask();
TBool DoTaskStep();
void EndTask();
...
};TBool CLongRunningCalculation :: DoTaskStep() {
// 执行一个任务步骤,如果还有任务要做则返回ETrue,如果任务完成了,返回EFalse
}_LIT(KExPanic, "CActiveExample");class CBackgroundRecalc : public CActive {
public:
// NewL,析构函数等
public:
void PerformRecalculation(TRequestStatus & aStatus);
protected:
CBackgroundRecalc();
void ConstructL();
void Complete();
virtual void RunL();
virtual void DoCancel();
private:
CLongRunningCalculation * iCalc;
TBool iMoreToDo;
TRequestStatus * iCallerStatus;
};CBackgroundRecalc :: CBackgroundRecalc() : CActive(EPriorityIdle) {
CActiveScheduler :: Add(this);
}void CBackgroundRecalc :: PerformRecalculation(TRequestStatus & aStatus) {
iCallerStatus = &aStatus;
*iCallerStatus = KRequestPending;
__ASSERT_ALWAYS(!IsActive(), User :: Panic(KExPanic, KErrInUse));
iMoreToDo = iCalc -> StartTask();
Complete();
}void CBackgroundRecalc :: Complete() {
TRequestStatus * status = &iStatus;
User :: RequestComplete(status, KErrNone);
SetActive();
}void CBackgroundRecalc :: RunL() {
if(!MoreToDo) {
iCalc -> EndTask();
User :: RequestComplete(iCallerStatus, iStatus.Int());
} else {
iMoreToDo = iCalc -> DoTaskStep();
Complete();
}
}void CBackgroundRecalc :: DoCancel() {
if(iCalc) {
iCalc -> EndTask();
}
if(iCallerStatus) {
User :: RequestComplete(iCallerStatus, KErrCancel);
}
} 3.多线程(通俗的说,就是活动对象开启另外一个线程来处理请求,这样不会阻塞某些重要的请求完成)
_LIT(KThreadName, "ExampleThread");
TInt SynchronousTask(); class CAsyncTask : public CActive {
public:
~CAsyncTask();
static CAsyncTask * NewLC();
void DoAsyncTask(TRequestStatus & aStatus);
protected:
virtual void DoCancel();
virtual void RunL();
virtual TInt RunError(TInt anError);
private:
CAsyncTask();
void ConstructL();
private:
TRequestStatus * iCaller;
RThread iThread;
};CAsyncTask :: CAsyncTask() : CActive(EPriorityStandard) {
CActiveScheduler :: Add(this);
}CAsyncTask :: ~CAsyncTask() {
Cancel();
}void CAsyncTask :: DoAsyncTask(TRequesStatus & aStatus) {
if(IsActive()) {
TRequestStatus * status = &aStatus;
User :: RequestComplete(status, KErrAlreadyExits);
return;
}
iCaller = &aStatus;
TInt res = iThread.Create(KThreadName, ThreadEntryPoint, KDefaultStackSize, NULL, NULL);
if(KErrNone != res) {
User :: RequestComplete(iCaller, res);
} else {
*iCaller = KRequestPending;
iStatus = KRequesPending;
SetActive();
iThread.Logon(iStatus);
iThread.Resume();
}
}TInt CAsyncTask :: ThreadEntryPoint(TAny * /* aParameters */) {
TInt res = SynchronousTask();
RThread().Kill(res);
return KErrNone;
}void CAsyncTask :: DoCancel() {
TExitType threadExitType = iThread.ExitType();
if(EExitPending == threadExitType) {
iThread.LogonCancel();
iThread.Kill(KErrCancel);
iThread.Close();
User :: RequestComplete(iCaller, KErrCancel);
}
}void CAsyncTask :: RunL() {
TExitType threadExitType = iThread.ExitType();
if(EExitPending == threadExitType) {
iThread.Kill(KErrNone);
}
User :: RequestComplete(iCaller, iStatus.Int());
iThread.Close();
}TInt CAsyncTask :: RunError(TInt anError) {
if(iCaller) {
User :: RequestComplete(iCaller, anError);
}
return KErrNone;
}
发表时间:2008-12-18 2:12:59 浏览次数:214
Symbian中活动对象的使用是很频繁的(活动对象的理论我不多说了,关心的朋友自己去查资料,跟Windows平台中的ActiveX对象一个样,对事件的驱动和处理过程也跟它一样,或者说,举个简单的例子,跟Ajax的异步传输一样.因为Symbian的活动对象本来就是用于异步请求的事件处理的).使用活动对象的典型方式我认为有三个: 1.状态机(通俗的说就是在同一线程同一活动对象中处理多步骤的异步请求)class CServiceProvider : public CBase {
public:
static CServiceProvider * NewL();
~CServiceProvider() {};
public:
void GetData(const TDesC& aSource, HBufC8 * aData, TRequestStatus & aStatus);
void CancelGetData();
TInt TranslateData(TDes8 & aData);
void SendData(const TDesC & aTarget, const TDesC8 & aData, TRequestStatus & aStatus);
void CancelSendData();
protected:
CServiceProvider() {};
};void CServiceProvider :: GetData(const TDesC & aSource, HBufC8 * aData, TRequestStatus & aStatus) {
aStatus = KRequestPending;
// 用RFile::Read()的异步重载形式从aSource中获取数据,并写入aData(如果必要,对其
// 重新分配空间),当读取完成,则由文件服务器将aStatus标为完成状态
}void CServiceProvider :: CancelGetData() {...}void CServiceProvider :: TranslateData(TDes8 & aData) {
// 同步解析数据并写入同一个描述符中
...
return translationResult;
}void CServiceProvider :: SendData(const TDesC & aTarget, const TDesC8 & aData, TRequestStatus & aStatus) {
aStatus = KRequestPending;
// 用RFile::Write()的异步重载形式向aTarget中写入数据,该函数在完成时设置aStatus状态
...
}void CServiceProvider :: CancelSendData() {...}const TInt KStandardDataLen = 1024;class CStateMachine : public CActive {
public:
~CStateMachine();
state CStateMachine * NewLC();
void SendTranslatedDate(const TDesC & aSource, const TDesC & aTarget, TRequestStatus &);
protected:
enum TState {EIdle, EGet, ETranslate, ESend};
protected:
CStateMachine();
void InitializeL(const TDesC & aTarget);
void Cleanup();
protected:
virtual void DoCancel();
virtual void RunL();
// RunError()我没有实现,因为RunL()在这个例子中不会Leave,但是这个声明是必须的(受C++语法限制)
virtual TInt RunError(TInt aError);
private:
CServiceProvider * iService;
TState iState;
private:
HBufC * iTarget;
HBufC8 * iStorage;
TRequestStatus * iClientStatus;
};CStateMachine :: CStateMachine() : CActive(EPriorityStandard) {
CActiveScheduler :: Add(this);
}CStateMachine :: ~CStateMachine() {
Cancel();
Cleanup();
}void CStateMachine :: InitializeL(const TDesC & aTarget) {
// 将其保存起来,后面传递给CServiceProvider
iTarget = aTarget.AllocL();
// 保存接收到的数据
iStorage = HBufC8::NewL(KStandardDataLen);
}void CStateMachine :: Cleanup() {
iState = EIdle;
delete iTarget;
iTarget = NULL;
delete iStorage;
iStorage = NULL;
}void CStateMachine :: SendTranslatedData(const TDesC & aSource, const TDesC & aTarget, TRequestStatus & aStatus) {
__ASSERT_ALWAYS(!IsActive, User::Panic(KExPanic, KErrInUse));
ASSERT(EIdle == iState);
iClientStatus = &aStatus;
*iClientStatus = KRequestPending;
TRAPD(r, InitializeL(aTarget));
if(KErrNone != r) {
Cleanup();
User::RequestComplete(iClientStatus, r);
} else {
iService -> GetData(aSource, iStorage, iStatus);
iState = EGet;
SetActive();
}
}void CStateMachine :: RunL() {
ASSERT(EIdle != iState);
if(KErrNone != iStatus.Int()) {
User :: RequestComplete(iClientStatus, iStatus.Int());
Cleanup();
} else {
if(EGet == iState) {
TPtr8 ptr(iStroage.Des());
iService -> TranslateData(ptr);
iState = ETranslate;
TRequestStatus * stat = &iStatus;
User::RequestComplete(stat, r);
SetActive();
} else if(ETranslate == iState) {
TInt r = iService -> SendData(*iTarget, *iStorage, iStatus);
iState = ESend;
SetActive();
} else {
ASSERT(ESend == iState);
User :: RequestComplete(iClientStatus, iStatus.Int());
Cleanup();
}
}
}void CStateMachine :: DoCancel() {
if(iService) {
if(CStateMachine :: EGet == iState) {
iService -> CancelGetData();
} else if(CStateMachine :: ESend == iState) {
iService -> CancelSendData();
}
}
if(iClientStatus) {
User :: RequestComplete(iClientStatus, KErrCancel);
}
} 2.长线任务(通俗的说,也就是在一个优先级低的活动对象中持续处理一个分成很多步的任务,这些任务可以不是异步的,每个步骤之间是自驱动或者叫自完成的)class CLongRunningCalculation : pulbic CBase {
public:
static CLongRunningCalculation * NewL();
TBool StartTask();
TBool DoTaskStep();
void EndTask();
...
};TBool CLongRunningCalculation :: DoTaskStep() {
// 执行一个任务步骤,如果还有任务要做则返回ETrue,如果任务完成了,返回EFalse
}_LIT(KExPanic, "CActiveExample");class CBackgroundRecalc : public CActive {
public:
// NewL,析构函数等
public:
void PerformRecalculation(TRequestStatus & aStatus);
protected:
CBackgroundRecalc();
void ConstructL();
void Complete();
virtual void RunL();
virtual void DoCancel();
private:
CLongRunningCalculation * iCalc;
TBool iMoreToDo;
TRequestStatus * iCallerStatus;
};CBackgroundRecalc :: CBackgroundRecalc() : CActive(EPriorityIdle) {
CActiveScheduler :: Add(this);
}void CBackgroundRecalc :: PerformRecalculation(TRequestStatus & aStatus) {
iCallerStatus = &aStatus;
*iCallerStatus = KRequestPending;
__ASSERT_ALWAYS(!IsActive(), User :: Panic(KExPanic, KErrInUse));
iMoreToDo = iCalc -> StartTask();
Complete();
}void CBackgroundRecalc :: Complete() {
TRequestStatus * status = &iStatus;
User :: RequestComplete(status, KErrNone);
SetActive();
}void CBackgroundRecalc :: RunL() {
if(!MoreToDo) {
iCalc -> EndTask();
User :: RequestComplete(iCallerStatus, iStatus.Int());
} else {
iMoreToDo = iCalc -> DoTaskStep();
Complete();
}
}void CBackgroundRecalc :: DoCancel() {
if(iCalc) {
iCalc -> EndTask();
}
if(iCallerStatus) {
User :: RequestComplete(iCallerStatus, KErrCancel);
}
} 3.多线程(通俗的说,就是活动对象开启另外一个线程来处理请求,这样不会阻塞某些重要的请求完成)
_LIT(KThreadName, "ExampleThread");
TInt SynchronousTask(); class CAsyncTask : public CActive {
public:
~CAsyncTask();
static CAsyncTask * NewLC();
void DoAsyncTask(TRequestStatus & aStatus);
protected:
virtual void DoCancel();
virtual void RunL();
virtual TInt RunError(TInt anError);
private:
CAsyncTask();
void ConstructL();
private:
TRequestStatus * iCaller;
RThread iThread;
};CAsyncTask :: CAsyncTask() : CActive(EPriorityStandard) {
CActiveScheduler :: Add(this);
}CAsyncTask :: ~CAsyncTask() {
Cancel();
}void CAsyncTask :: DoAsyncTask(TRequesStatus & aStatus) {
if(IsActive()) {
TRequestStatus * status = &aStatus;
User :: RequestComplete(status, KErrAlreadyExits);
return;
}
iCaller = &aStatus;
TInt res = iThread.Create(KThreadName, ThreadEntryPoint, KDefaultStackSize, NULL, NULL);
if(KErrNone != res) {
User :: RequestComplete(iCaller, res);
} else {
*iCaller = KRequestPending;
iStatus = KRequesPending;
SetActive();
iThread.Logon(iStatus);
iThread.Resume();
}
}TInt CAsyncTask :: ThreadEntryPoint(TAny * /* aParameters */) {
TInt res = SynchronousTask();
RThread().Kill(res);
return KErrNone;
}void CAsyncTask :: DoCancel() {
TExitType threadExitType = iThread.ExitType();
if(EExitPending == threadExitType) {
iThread.LogonCancel();
iThread.Kill(KErrCancel);
iThread.Close();
User :: RequestComplete(iCaller, KErrCancel);
}
}void CAsyncTask :: RunL() {
TExitType threadExitType = iThread.ExitType();
if(EExitPending == threadExitType) {
iThread.Kill(KErrNone);
}
User :: RequestComplete(iCaller, iStatus.Int());
iThread.Close();
}TInt CAsyncTask :: RunError(TInt anError) {
if(iCaller) {
User :: RequestComplete(iCaller, anError);
}
return KErrNone;
}
Symbian中使用活动对象的三种典型设计
Symbian中使用活动对象的三种典型设计111
Symbian OS:活动对象与活动调度器
javascript中Location对象的使用(转)
Symbian 上关于位图的使用
拷贝对象的三种方式
三种典型的国内避税法
三种典型的国内避税法
Java中使用JCOM操作Office对象
如何在ado中使用connection 对象?
Symbian中有用的宏整理
面向对象的设计原则三 - 接口隔离原则 - 森林狼 - JavaEye技术网站
市纪委在创先争优活动中充分发挥典型作用
Symbian中的动态集合Rarray的使用(页 1) - Symbian开发 - JBL...
一些面向对象的设计法则
面向对象的应用服务层设计
面向对象的应用服务层设计
我使用的手机软件『Nokia Symbian S60 V3』
关于RMsgQueue类的使用 - World of Symbian - CSDN博客
语文课堂活动的设计技巧
面向对象的设计原则-类设计原则
使用JAXB从一个对象模型中产生XML文档
61条面向对象设计的经验原则61条面向对象设计的经验原则
面向对象的设计原则-类设计原则 ——希赛网软件工程频道面向对象