现在的位置: 首页 > 综合 > 正文

symbian 活动对象的时候(如果实现一个长期运行的活动对象)

2013年09月07日 ⁄ 综合 ⁄ 共 2796字 ⁄ 字号 评论关闭

活动对象在symbian中应该来说是使用比较常用的一中机制,在这里总结下使用活动对象的几种方式。

活动对象的定义:一种模拟多线程实现多任务的一种机制,简单的理解应该是这样的。

具体使用:

1。配合RTime类来使用,基本上很多书上都是这么写(白皮书上就是这么讲的),我在这里就不多说。

2。配合一些异步函数。比如写文件的时候用到的Write函数,原型是:
 IMPORT_C void Write(const TDesC8 &aDes, TRequestStatus &aStatus);

 可以看到这里的参数和其他的几个函数有点差别,这里有个TRequestStatus &aStatus参数,于是我们就联想到,这个参数在活动对象中有用到。
 用法如下:
 a。激活活动对象
 void CAsyncFile::FileWrite(const TDesC8& aDes)
 {
 TInt pos = 0;
 iFile.Seek(ESeekEnd, pos);
 iFile.Write(aDes, iStatus);
 SetActive();
 }
 b.处理活动对象的RunL函数
 void CAsyncFile::RunL()
 {
  switch(iStatus.int())
  {
  case KErrNone:
  //do something
  break;
  }
 }
 c.往后的一些处理都和1中的一样
 
 还有比如连网的时候使用的IMPORT_C void RConnect::Start(TConnPref &aPref, TRequestStatus &aStatus);都是如同2中的使用方法
 
3。长时间的运行任务,用活动对象实现。我如要是为了说下这种方法所以第1和2都讲的比较简单

这种方法应该也是常用的,但是可以网上资料没有这么实现的,贴下详细代码:
 a。活动对象的.h
 class CAoTest : public CActive
   {
  private:
   void RunL();
   TInt RunError(TInt aError);
   void DoCancel();
  public:
   CAoTest();
   ~CAoTest();
   void Start();
   };
  
  b.活动对象的.cpp
  CAoTest::CAoTest() : CActive(EPriorityStandard)
   {
   CActiveScheduler::Add(this);
   }
  
  CAoTest::~CAoTest()
   {
   Cancel();
   }
   /*
   在调用Start函数后会掉用这个函数,我们在这里做了些处理,这样直接让活动对象调用完RunL函数后,
   后再次调用RunL()函数,实现一个长期运行的活动对象
   */
  void CAoTest::RunL()
   {
   TRequestStatus *myStatus = &iStatus;
   User::RequestComplete(myStatus,KErrNone);
   SetActive();
   }
   /*
   处理取消活动对象,一般情况下可以这么写,都的时候需要空着,具体在使用的时候再体会吧
   */
  void CAoTest::DoCancel()
   {
  
   TRequestStatus* pS = &iStatus;
   User::RequestComplete(pS, KErrCancel);
   
   }
   /*
   启动函数,调用启动活动对象。这里需要注意的是需要设置iStatus这个值,直接设置为KRequestPending
   也可以,但是一般不推荐这样直接赋值(初始化的时候可以这样),容易出现E32Ueser-cbase 46(出现游
   离信号),可以像我下面那样设置
   */
  void CAoTest::Start()
   {
  
  // Cancel();
   TRequestStatus* pS = &iStatus;
   User::RequestComplete(pS, KErrNone);
   if(!IsActive())
    SetActive();
   }
   /*
   处理Runl的异常退出,因此在Runl中就不用使用TRDP等异常处理的机制来处理异常了
   */
  TInt CAoTest::RunError(TInt aError)
   {
   TInt nerr = aError;
   return nerr;
   }
  
  CHelloWorldA0AppView* CHelloWorldA0AppView::NewL(const TRect& aRect)
   {
   CHelloWorldA0AppView* self = CHelloWorldA0AppView::NewLC(aRect);
   CleanupStack::Pop(self);
   return self;
   }
   
   c.使用活动对象
   直接建立一个Hello world的GUI工程
   然后在cantainer中 定义个成员
   CAoTest *iaoTest;
   然后在cantainer的ConstructL中实例化
   
   void CHelloWorldA0AppView::ConstructL(const TRect& aRect)
   {
   // Create a window for this application view
   CreateWindowL();
   
   iaoTest = new CAoTest;
   // Set the windows size
   SetRect(aRect);
  
   // Activate the window, which makes it ready to be drawn
   ActivateL();
   
   iaoTest->Start();
   }
   
   这个时候可以debug下单步运行,在RunL函数看见会不停的回调这个函数。这个时候一个长期运行的活动对象就成功实现
   
   
   
一般会遇到的问题问题:
   1。一般在使用活动对象的时候遇到的比较常见的panic就是E32Ueser-cbase 46,对应的问题是说游离的信号,
   2。一般可能会出现游离信号的情况是:
    a.忘记激活活动对象,意思是忘记调用SetActive
    b.忘记初始化iStatus为KRequestding
    c.出现两次请求或者完成了两次请求,这种情况一般是 因为手动设置iStatus造成的
   3.活动对象中不要直接调用DoCancel,而应该通过调用Cancel来间接的调用DoCancel
   4.活动对象析构的时候一般都是会调用Cancel函数的
   
   

抱歉!评论已关闭.