symbian 活動對象的時候(如果實現一個長期運行的活動對象)

活動對象在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函數的
   
   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章