活動(dòng)對(duì)象和一個(gè)活動(dòng)調(diào)度器共同提供了非搶先式多任務(wù),可用于替代Symbian OS中的多線程,。使用活動(dòng)對(duì)象可獲得的好處是:與使用線程相比較,,它編程簡(jiǎn)潔,且CPU的效率更高,。 Symbian OS v8.0中引入了兩個(gè)新機(jī)制,,即發(fā)行預(yù)訂和消息隊(duì)列。它們使線程間和進(jìn)程間的信息共享更為方便,。它們并不提供除線程和活動(dòng)對(duì)象以外的其他選擇,,但卻可能對(duì)運(yùn)行于多線程環(huán)境中的客戶端代碼產(chǎn)生結(jié)構(gòu)決策方面的影響。 多任務(wù)是用在操作系統(tǒng)中的一項(xiàng)技術(shù),,以便在幾個(gè)獨(dú)立任務(wù)間共享一個(gè)處理器[ODICT,,多任務(wù)]。 在協(xié)同式多任務(wù)中,,正在運(yùn)行的任務(wù)將決定什么時(shí)候放棄對(duì)CPU的使用,,而在搶先式多任務(wù)中,當(dāng)前任務(wù)運(yùn)行了一段被稱為“時(shí)間片”的固定時(shí)間段后,,被一個(gè)名為“調(diào)度器”的系統(tǒng)進(jìn)程掛起,。在這兩種情況下,,調(diào)度器負(fù)責(zé)選擇下一個(gè)要運(yùn)行的任務(wù),并(重)啟它,。 多線程意味著:以一種意在最小化線程切換所需時(shí)間的方式在多個(gè)任務(wù)(或“線程”)間共享一個(gè)單一的CPU,。這是通過在不同的線程間共享盡可能多的程序執(zhí)行環(huán)境實(shí)現(xiàn)的,從而當(dāng)切換線程時(shí),,只需要極少的狀態(tài)儲(chǔ)存和恢復(fù),。[ODICT,多任務(wù)],。 Symbian OS實(shí)現(xiàn)了搶先式多線程,,因此它能同時(shí)運(yùn)行多個(gè)應(yīng)用和多個(gè)服務(wù)器。一些活動(dòng)對(duì)象用于在某個(gè)單一線程中實(shí)現(xiàn)非搶先式多任務(wù),。 線程間的調(diào)度由Symbian OS自動(dòng)完成,。程序員只是創(chuàng)建一個(gè)線程,并將其設(shè)置為能運(yùn)行所需的任務(wù),。系統(tǒng)調(diào)度器向每個(gè)線程自動(dòng)分配CPU時(shí)間,。線程間的切換如此頻繁,以至一個(gè)線程的執(zhí)行看上去是連續(xù)的,。 某個(gè)線程可以有一個(gè)活動(dòng)調(diào)度器,,它調(diào)度各活動(dòng)對(duì)象間的執(zhí)行時(shí)間(為該線程分配的時(shí)間片)??梢园鸦顒?dòng)對(duì)象視為線程的子任務(wù),。然而,活動(dòng)調(diào)度器在調(diào)度過程中使用了一個(gè)非搶先方法:正在執(zhí)行中的活動(dòng)對(duì)象不會(huì)被中斷(如同線程執(zhí)行一樣),。當(dāng)活動(dòng)對(duì)象完成其任務(wù)并把控制權(quán)交還給活動(dòng)調(diào)度器時(shí),,它自己會(huì)做出決定。然后,,活動(dòng)調(diào)度器就可以在執(zhí)行過程中選擇另一個(gè)活動(dòng)對(duì)象,。 在很多情況下,線程中都安裝有一個(gè)活動(dòng)調(diào)度器,。在這種情況下,,程序員可以立即使用活動(dòng)對(duì)象。例如,,用戶界面(UI)應(yīng)用(.app)有主線程,主線程有一個(gè)活動(dòng)調(diào)度器,。然而,,當(dāng)寫服務(wù)器(.exe)或創(chuàng)建自己的線程時(shí),必須在這些活動(dòng)對(duì)象能被使用之前先安裝這個(gè)活動(dòng)調(diào)度器,。 活動(dòng)對(duì)象的典型用法是:在某個(gè)應(yīng)用中處理一些事件,。例如,,應(yīng)用框架使用一些活動(dòng)對(duì)象來處理按鍵和屏幕更新。處理該事件的活動(dòng)對(duì)象往往會(huì)發(fā)起一個(gè)對(duì)已被該程序員所重置的方法(例如leKeyEventL())的回調(diào),。當(dāng)這類方法被重置后,,需要理解的是:該方法是由某個(gè)活動(dòng)對(duì)象所調(diào)用的,這意味著,,在該方法返回之前沒有其他活動(dòng)對(duì)象可以運(yùn)行,。 客戶端/服務(wù)器結(jié)構(gòu)和異步方法 Symbian OS具有一個(gè)先進(jìn)的微內(nèi)核結(jié)構(gòu),它使用客戶端/服務(wù)器結(jié)構(gòu)模式,。為Symbian OS編寫的那些應(yīng)用通常是通過服務(wù)器使用各種資源的客戶端,。該服務(wù)器往往提供一個(gè)R-類,這是一個(gè)針對(duì)各種服務(wù)器服務(wù)的代理,。 各種R- classe具有兩種方法: 1. 異步方法,。某個(gè)客戶端線程調(diào)用該方法,它構(gòu)造一則消息并將其發(fā)送到服務(wù)器線程,。當(dāng)發(fā)送消息之后,,該客戶端線程將從該方法中返回。 服務(wù)器端有自己可接受各種消息的線程,。它讀取所傳遞的數(shù)據(jù)并處理請(qǐng)求,。當(dāng)服務(wù)器處理完請(qǐng)求后,它會(huì)對(duì)該客戶端線程發(fā)出提示:該請(qǐng)求已完成,,并傳遞一個(gè)作為結(jié)果的完成代碼,。 客戶端線程必須處理這種提示和結(jié)構(gòu)代碼,但可以在某個(gè)適當(dāng)?shù)臅r(shí)間進(jìn)行,。 2, 同步方法,。消息傳輸和服務(wù)器處理過程類似于異步方法,但是調(diào)用R-類方法的客戶端線程在消息發(fā)送之后并不返回,。相反,,它掛起該線程的執(zhí)行,并等待來自服務(wù)器的有關(guān)該請(qǐng)求已完成的提示,。 當(dāng)服務(wù)器向客戶端發(fā)送響應(yīng)時(shí),,Symbian OS會(huì)去喚醒被掛起的客戶端線程。然后客戶端線程會(huì)去處理那個(gè)完成代碼,,此時(shí)如果完成代碼顯示服務(wù)器端有錯(cuò),,就會(huì)去處理這些錯(cuò)誤,并返回,。 當(dāng)調(diào)用某個(gè)同步方法時(shí),,客戶端線程會(huì)被阻塞,直到服務(wù)器線程向其提示:該請(qǐng)求已經(jīng)完成,。在許多情況下,,客戶端程序必須更新其UI并處理用戶輸入事件,。如果同步方式要用很長(zhǎng)時(shí)間完成,用戶體驗(yàn)將由于這些事件得不到處理而受到損害,。 當(dāng)程序使用一些異步方法時(shí),,客戶端線程能處理這些事件并更新UI,而服務(wù)器則會(huì)完成該請(qǐng)求,。當(dāng)服務(wù)器處理完請(qǐng)求后,,客戶端將得到有關(guān)請(qǐng)求已完成的提示。該客戶端以處理其他事件的相同方式處理該提示,。在這種情況下用戶體驗(yàn)將非常良好,,因?yàn)槌绦驎?huì)響應(yīng)用戶的行為,從而使一切看上去比較順利,。 使用一些同步方法要比使用異步方法更為容易,。當(dāng)使用某個(gè)異步方法時(shí),調(diào)用程序必須記住對(duì)每一個(gè)異步方法的調(diào)用,,并追蹤其是否完成,。當(dāng)同步方式返回時(shí),其結(jié)果可馬上得到處理,,因此就沒有必要追蹤那些請(qǐng)求的完成情況,。 然而,Symbian OS提供了框架,,該框架使各種異步服務(wù)的使用更為便捷:活動(dòng)對(duì)象和活動(dòng)調(diào)度器,。使用異步接口,而不是同步接口的原因之一就是效率和良好的用戶體驗(yàn),。 區(qū)別異步方法還是同步方法是很容易的——異步方法必須具有TrequestStatus作為其參數(shù)之一,。這就是處理請(qǐng)求后,服務(wù)器儲(chǔ)存完成代碼所處的值,。 各種同步方法并沒有這種參數(shù),,因?yàn)樗鼈冊(cè)趶脑摲椒ǚ祷厍暗却渫瓿桑?duì)結(jié)果進(jìn)行處理,。各種異步方式的優(yōu)秀范例是:RFile中的一些讀寫方法: void RFile::Read(TInt aPos, TDes8& aDes, TRequestStatus& aStatus) const; void RFile::Write(const TDesC8& aDes, TRequestStatus& aStatus); RFile還提供來自某些相同方法的實(shí)現(xiàn),。它們的聲明都相似,但是它們不把TRequestStatus作為一個(gè)參數(shù): TInt RFile::Read(TDes8& aDes) const; TInt RFile::Write(const TDesC8& aDes); 活動(dòng)對(duì)象和活動(dòng)調(diào)度器 動(dòng)機(jī) 事件驅(qū)動(dòng)環(huán)境中的一些任務(wù)(如各種UI應(yīng)用中的一些任務(wù))處理來自系統(tǒng)的一些事件,。程序代碼往往調(diào)用某個(gè)異步方法,,它處理一個(gè)請(qǐng)求。當(dāng)該請(qǐng)求完成之后,,客戶端得到提示,,處理結(jié)果,且很有可能發(fā)起一個(gè)新的請(qǐng)求。 如果用一些線程來實(shí)現(xiàn)某些任務(wù),,針對(duì)每一個(gè)事件源都必須有一個(gè)線程。例如,,某個(gè)線程可處理鍵按下,。當(dāng)按下某個(gè)鍵后,它可能會(huì)去請(qǐng)求服務(wù)器發(fā)出一個(gè)提示,。然后該線程就會(huì)被掛起,,直到服務(wù)器喚醒該客戶端線程去處理那次按鍵。同時(shí),,可能還存在著另一個(gè)線程,,它以某個(gè)異步(或阻斷同步)方法以某種類似方式從socket讀取數(shù)據(jù)。 各種活動(dòng)對(duì)象提供了事件處理的便捷方式,。當(dāng)發(fā)出一個(gè)異步請(qǐng)求并當(dāng)服務(wù)器完成該請(qǐng)求時(shí),,活動(dòng)對(duì)象的內(nèi)部屬性得到了傳遞,以取得響應(yīng)代碼,?;顒?dòng)調(diào)度器關(guān)注該活動(dòng)對(duì)象的運(yùn)行,及當(dāng)該請(qǐng)求在服務(wù)器端得到完成后對(duì)結(jié)果的處理,。 有很多理由解釋在Symbian OS中為什么用活動(dòng)對(duì)象,,而不是線程,來處理各種事件,。例如: 1. 線程間的通信比活動(dòng)對(duì)象間的通信緩慢且困難些(活動(dòng)對(duì)象在同一個(gè)線程中運(yùn)行,,因此它們不需要任何特殊方法來共享數(shù)據(jù))。 2. 線程間的場(chǎng)景切換消耗CPU周期,,從而使其性能表現(xiàn)下降,。活動(dòng)對(duì)象并不像線程那樣會(huì)被中斷,,因此并不需要在各個(gè)切換間儲(chǔ)存并恢復(fù)CPU及內(nèi)存映射單元(Memory Mapping Unit,,MMU)的狀態(tài)。 3. 許多資源不能在線程間共享,。由于活動(dòng)對(duì)象用一個(gè)線程運(yùn)行,,它們可以共享資源。 4. 在線程間訪問內(nèi)存或訪問其他共享內(nèi)存通常需要對(duì)同步更新提供保護(hù),。這由信號(hào)量(semaphores)完成,,這可能導(dǎo)致代碼的復(fù)雜化,并造成性能下降,?;顒?dòng)對(duì)象不用擔(dān)心同步問題,因?yàn)樗鼈兪且阅撤N非搶先方式調(diào)度的。 Symbian OS基于微內(nèi)核結(jié)構(gòu),。各種服務(wù)的使用都通過異步接口,。活動(dòng)對(duì)象和活動(dòng)調(diào)度器針對(duì)異步服務(wù)的使用提供了方便的框架:某個(gè)活動(dòng)對(duì)象發(fā)起一些異步請(qǐng)求,,并處理該請(qǐng)求,。有一個(gè)變量用于指出服務(wù)器何時(shí)已完成該請(qǐng)求?;顒?dòng)調(diào)度器追蹤那些活動(dòng)對(duì)象,,當(dāng)其發(fā)現(xiàn)有一個(gè)請(qǐng)求已完成時(shí),它會(huì)調(diào)用所分配的活動(dòng)對(duì)象的RunL()方法,,而后者會(huì)去處理該服務(wù)器響應(yīng),。 繼承自CActive的某個(gè)類被稱為一個(gè)活動(dòng)對(duì)象。CActive被如下聲明: class CActive : public CBase { public: enum TPriority { EPriorityIdle=-100, EPriorityLow=-20, EPriorityStandard=0, EPriorityUserInput=10, EPriorityHigh=20, }; public: IMPORT_C ~CActive(); IMPORT_C void Cancel(); IMPORT_C void Deque(); IMPORT_C void SetPriority(TInt aPriority); inline TBool IsActive() const; inline TBool IsAdded() const; inline TInt Priority() const; protected: IMPORT_C CActive(TInt aPriority); IMPORT_C void SetActive(); // Pure virtual virtual void DoCancel() =0; virtual void RunL() =0; IMPORT_C virtual TInt RunError(TInt aError); public: TRequestStatus iStatus; private: TBool iActive; TPriQueLink iLink; friend class CActiveScheduler; friend class CServer; friend class CServer2; }; 通常, 活動(dòng)對(duì)象用于發(fā)出一個(gè)異步調(diào)用,,并當(dāng)服務(wù)供應(yīng)商處理完請(qǐng)求后去處理這些結(jié)果,。流程如下: 1. 創(chuàng)建活動(dòng)對(duì)象并將其添加到活動(dòng)調(diào)度器中 2. 要求活動(dòng)對(duì)象創(chuàng)建一個(gè)異步請(qǐng)求。該活動(dòng)對(duì)象將其iStatus作為針對(duì)該異步方法的一個(gè)參數(shù)傳遞.這個(gè)異步方法將iStatus 變量設(shè)定為KRequestPending,,以表示該活動(dòng)對(duì)象正在等待某個(gè)請(qǐng)求的完成,,并將請(qǐng)求消息發(fā)送給服務(wù)供應(yīng)商。然后,,異步方式返回,。在活動(dòng)對(duì)象的方法返回之前,它調(diào)用SetActive()方法,,后者向活動(dòng)調(diào)度器指出:必須追蹤這個(gè)活動(dòng)對(duì)象的完成,。 3. 當(dāng)服務(wù)供應(yīng)商完成請(qǐng)求之后,它將結(jié)果代碼賦予iStatus變量,。 4, 活動(dòng)調(diào)度器追蹤被激活的活動(dòng)對(duì)象,。如果活動(dòng)對(duì)象的iStatus不是KRequestPending,就調(diào)用其RunL()方法,,因?yàn)榉?wù)器端的請(qǐng)求已經(jīng)就緒,。 5. Method RunL() processes the result code of the previous asynchronous request. 方法RunL()處理先前的異步請(qǐng)求的結(jié)果代碼。 上面講述的范例十分簡(jiǎn)單:活動(dòng)對(duì)象被用于僅完成一個(gè)異步請(qǐng)求,。然而,,RunL()本可以發(fā)出一個(gè)新的異步請(qǐng)求,激活自己,,并等待,,直到活動(dòng)調(diào)度器再一次調(diào)用其RunL()。 為了正確使用活動(dòng)對(duì)象,,理解某些特性和行為是很有幫助的,。 1. 狀態(tài),。 當(dāng)某個(gè)活動(dòng)對(duì)象調(diào)用了一個(gè)異步方法,它將其iStatus作為參數(shù)傳遞,。服務(wù)供應(yīng)商立即將狀態(tài)設(shè)定為KRequestPending,,這表示:服務(wù)供應(yīng)商正在處理該請(qǐng)求。 2. 活動(dòng)性,。當(dāng)某個(gè)活動(dòng)對(duì)象發(fā)出了一個(gè)異步請(qǐng)求,,就必須以SetActive()方法對(duì)其進(jìn)行激活。這是因?yàn)椋夯顒?dòng)調(diào)度器只對(duì)活動(dòng)著的活動(dòng)對(duì)象進(jìn)行追蹤,。當(dāng)活動(dòng)對(duì)象被激活后,它將保持其活動(dòng)狀態(tài)直到活動(dòng)調(diào)度器調(diào)用其RunL()方法或當(dāng)前的任務(wù)已被刪除時(shí)為止,。 3. 優(yōu)先權(quán),。活動(dòng)調(diào)度器按優(yōu)先權(quán)順序追蹤各個(gè)活動(dòng)對(duì)象,。針對(duì)活動(dòng)對(duì)象的優(yōu)先權(quán)在構(gòu)造時(shí)給出,。當(dāng)活動(dòng)對(duì)象沒被激活時(shí),可以用SetPriority()方法修改其優(yōu)先權(quán)(這樣某個(gè)請(qǐng)求就不再處于等待狀態(tài)),。 4. 結(jié)果處理,。當(dāng)某個(gè)活動(dòng)對(duì)象是活動(dòng)的,且其iStatus不是KRequestPending,,這意味著:服務(wù)供應(yīng)商已經(jīng)完成了該活動(dòng)對(duì)象所發(fā)出的請(qǐng)求,。當(dāng)活動(dòng)調(diào)度器發(fā)現(xiàn)這樣一個(gè)對(duì)象時(shí),它使這一對(duì)象不再活動(dòng)并調(diào)用其RunL()方法,。 方法RunL()是一個(gè)“純虛”方法,,因而必須在繼承類中實(shí)現(xiàn)。異步請(qǐng)求的結(jié)果代碼可以從iStatus參數(shù)中找到,。該方法的實(shí)現(xiàn)幾乎可以做任何事情,,但不能持續(xù)太長(zhǎng)時(shí)間! 注意:RunL()方法一定不能持續(xù)太久,,因?yàn)榛顒?dòng)對(duì)象是以非搶先方式調(diào)度的,。同一線程中所有其他活動(dòng)對(duì)象在RunL()執(zhí)行期間被阻斷。許多活動(dòng)對(duì)象(如鍵盤事件處理器和屏幕刷新器等)需要快速響應(yīng)這些事件,,因此不能阻斷太長(zhǎng)時(shí)間,。 1. 取消?;顒?dòng)對(duì)象正在執(zhí)行的任務(wù)必須能被取消,。當(dāng)調(diào)用活動(dòng)對(duì)象的Cancel()方法時(shí),活動(dòng)調(diào)度器調(diào)用該活動(dòng)對(duì)象的DoCancel()方法,,然后使這一對(duì)象不再活動(dòng),。試圖取消某個(gè)非活動(dòng)的活動(dòng)對(duì)象(因此無需等待任何請(qǐng)求的完成)不會(huì)產(chǎn)生任何效用 DoCancel()是一個(gè)“純虛”方法,,因此必須在某個(gè)具體繼承類中實(shí)現(xiàn)。該實(shí)現(xiàn)必須取消當(dāng)前正在等待中的異步請(qǐng)求,。 具有異步方法的那些類往往具有用于取消那些等待中請(qǐng)求的方法,。當(dāng)調(diào)用這種取消方法時(shí),服務(wù)供應(yīng)商將取消當(dāng)前請(qǐng)求并往往相應(yīng)地把iStatus設(shè)定為KErrCancel,。在客戶端線程從這個(gè)被取消的方法中返回之前,,它等待來自服務(wù)供應(yīng)商有關(guān)已經(jīng)取消該操作的提示。 2. 出錯(cuò)處理,?;顒?dòng)調(diào)度器捕捉RunL()方法的執(zhí)行。如果它出現(xiàn)了異常,,活動(dòng)調(diào)度器會(huì)調(diào)用該活動(dòng)對(duì)象的RunError()方法并將某個(gè)異常代碼作為參數(shù)傳遞出去,。如果RunError()返回一個(gè)非零返回碼,活動(dòng)調(diào)度器將發(fā)出當(dāng)前線程的資源緊缺警報(bào),。 RunError()方法是虛的,,且可以被重置。默認(rèn)實(shí)現(xiàn)返回作為一個(gè)參數(shù)傳遞的出錯(cuò)代碼(因此活動(dòng)調(diào)度器發(fā)出當(dāng)前線程的資源緊缺警報(bào)),。 活動(dòng)調(diào)度器 Symbian OS中的每個(gè)進(jìn)程都有一個(gè)線程,,即主線程。這個(gè)主線程為這個(gè)進(jìn)程創(chuàng)建一些額外的線程,。如果用到了活動(dòng)對(duì)象,,就必須為這個(gè)線程實(shí)例化活動(dòng)對(duì)象調(diào)度器,然后啟動(dòng)它以便對(duì)活動(dòng)對(duì)象進(jìn)行調(diào)度,。 Symbian OS的用戶界面應(yīng)用就是具有一個(gè)主線程的進(jìn)程,。應(yīng)用框架為這個(gè)主線程安裝一個(gè)活動(dòng)對(duì)象,。在活動(dòng)調(diào)度器中還有許多的活動(dòng)對(duì)象,,他們處理應(yīng)用事件(鍵盤按壓和屏幕更新請(qǐng)求)并實(shí)現(xiàn)對(duì)應(yīng)用程序員可能重置了的一些方法的回調(diào)。程序員可以使用由應(yīng)用框架所提供的默認(rèn)的活動(dòng)調(diào)度器,。 然而,,如果程序員創(chuàng)建了自己的某個(gè)線程,,默認(rèn)情況下并不存在一個(gè)針對(duì)該線程的活動(dòng)調(diào)度器??蓤?zhí)行程序(.exe)具有一個(gè)主線程,,如各種應(yīng)用一樣,但是該線程并沒有任何的活動(dòng)調(diào)度器,。要在這樣的線程中使用活動(dòng)對(duì)象,,程序員必須安裝活動(dòng)調(diào)度器,運(yùn)行它,,然后刪除它,。 使用自己的活動(dòng)調(diào)度器 要在某個(gè)不具備活動(dòng)調(diào)度器的線程中使用一些活動(dòng)對(duì)象,,程序員必須: 1. 用方法CActiveScheduler::Install()為那個(gè)線程創(chuàng)建并安裝一個(gè)活動(dòng)調(diào)度器。 2. 創(chuàng)建活動(dòng)對(duì)象并用方法CActiveScheduler::Add()將它們添加到那個(gè)活動(dòng)調(diào)度器中,。 3. 用這些活動(dòng)對(duì)象發(fā)起一個(gè)或多個(gè)異步請(qǐng)求,。 4. 用方法CActiveScheduler::Start()啟動(dòng)那個(gè)活動(dòng)調(diào)度器。 該活動(dòng)調(diào)度器的方法start()在其停止方法被調(diào)用前并不會(huì)返回,。這就是為何在這個(gè)調(diào)度器中必須有一些活動(dòng)對(duì)象來處理某些任務(wù)的原因,。當(dāng)這些任務(wù)得到處理之后,一個(gè)活動(dòng)對(duì)象必須以方法CActiveScheduler::Stop()停止該活動(dòng)調(diào)度器,。然后早先被調(diào)用的該活動(dòng)調(diào)度器方法CActiveScheduler::Start()返回,。 在啟動(dòng)活動(dòng)調(diào)度器之前其中必須有一些發(fā)出了一個(gè)異步請(qǐng)求的活動(dòng)對(duì)象。這是因?yàn)椋哼@個(gè)活動(dòng)調(diào)度器只運(yùn)行這樣一些活動(dòng)對(duì)象,,這些活動(dòng)對(duì)象的服務(wù)供應(yīng)商已經(jīng)提示其完成,。當(dāng)該活動(dòng)調(diào)度器被啟動(dòng)時(shí),如果并不存在任何等待中的未完成請(qǐng)求,,這個(gè)線程將被永遠(yuǎn)掛起。 LOCAL_C void doExampleL() { // Create and install the active scheduler CActiveScheduler* exampleScheduler= new (ELeave) CActiveScheduler; CleanupStack::PushL(exampleScheduler); CActiveScheduler::Install(exampleScheduler); // Create the service provider. Often, the // service provider is part of the active object CExampleServiceProvider* myServiceProvider= new (ELeave) CExampleServiceProvider; CleanupStack::PushL( myServiceProvider ); // Create the active object and issue the // first asynchronous request CExampleActiveObject * myActiveObject= new (ELeave) CExampleActiveObject( myServiceProvider ); CleanupStack::PushL(myActiveObject); myActiveObject->IssueRequest(); // Now we can start the active scheduler CActiveScheduler::Start(); // Remove the exampleScheduler and other // objects from cleanup stack and destroy them CleanupStack::PopAndDestroy(3); } 首先,,創(chuàng)建并安裝活動(dòng)調(diào)度器,。然后,創(chuàng)建一個(gè)活動(dòng)對(duì)象并將其添加到那個(gè)活動(dòng)調(diào)度器之中,。之后就用那個(gè)活動(dòng)對(duì)象發(fā)出一個(gè)請(qǐng)求,。活動(dòng)調(diào)度器已被啟動(dòng),?;顒?dòng)調(diào)度器追蹤那些活動(dòng)對(duì)象,當(dāng)其發(fā)現(xiàn)其中之一的請(qǐng)求完成時(shí),,它會(huì)調(diào)用其RunL(),。 當(dāng)這個(gè)范例活動(dòng)對(duì)象決定該活動(dòng)調(diào)度器應(yīng)該運(yùn)行這些活動(dòng)對(duì)象時(shí)(例如,當(dāng)程序行將終止時(shí)),,它會(huì)調(diào)用該活動(dòng)調(diào)度器的停止方法,。然后該活動(dòng)對(duì)象從其RunL()方法中返回,且該活動(dòng)調(diào)度器發(fā)現(xiàn):其停止方法已經(jīng)得到了調(diào)用,,并從其Start()方法中返回,。 |
|