Author: Sun Dongfeng
Date: 04/02/2008
Active Object is an important concept in Symbian. It is a mechanism that Symbian OS uses a single thread to implement multi-task asynchronous processing to save system resources.
The framwork of s60 itself also uses AO for multi-task implementation. For example, we can directly call the following code in s60 Eikon control based application to add our ao to the system cactivescheduler.
Void cactivetest3newclass: constructl ()
{
User: leaveiferror (itimer. createlocal (); // initialize Timer
Cactivescheduler: add (this); // Add to Scheduler
}
If you have custkit, devkit, or bak, you can trace the entry of the Symbian program.
Gldef_c tint e32main ()
{
Return eikstart: runapplication (newapplication );
}
You will find that the eikstart: runapplication actually calls cactivescheduler: Start (). This call starts a cactivescheduler and enters the cactivescheduler loop. Once the program enters the cactivescheduler loop, it will not jump out until the program ends.
This is similar to the Message Loop Mechanism in Windows:
While (getmessage (...))
{
Translatemessage (...);
Dispatchmessage (...);
}
Cactivescheduler maintains a wait loop, which is used to accept requests from all active objects and then handed over to the corresponding server program for processing. When the request is responded, the server generates an event, which is handled by the runl () function. After the event is processed, runl () the function can decide whether to send the next request or terminate the request.
For example, the following program continues sending requests after runl () processing, so that the program continuously loops:
Void cactivetest3newclass: runl () { Showdialog (icount ++ ); Setactive (); // tell scheduler a request is active } |
Of course, the above loop is too fast and sometimes "Jump table" appears ". A rtimer can be used for clock control:
Void cactivetest3newclass: runl () { Showdialog (icount ++ ); // Itimer. After (istatus, 1000000); // set for 1 sec later Setactive (); // tell scheduler a request is active } |
Since cactivescheduler is responsible for Ao scheduling, it is very important to understand the scheduling principles of cactivescheduler. The scheduling principles of cactivescheduler are divided into the following two parts:
① Check the added AO items one by one based on the AO priority.
Cactivescheduler has an AO table, which records the AO in the order of priority from large to small. Then, the priority of each AO determines who gets the server response first.
② Judge the isactive () value and istatus status of the AO currently traversed.
Set isactive () to etrue and istatus! = Krquestpending. After receiving the server response, execute the AO runl () method.
Among them, trequeststatus istatus is a state variable of the abstract base class cactive. It is an object of the trequeststatus class and encapsulates the status or error code provided when the server returns. When a request is sent, the active object passes the reference of istatus to the server. The server sets the value of istatus to krequestpedding and blocks other requests. When the request is complete, the server sets the value of istatus to kerrnone.
The following is an AO test example that I wrote to implement an animation:
/* ========================================================== ========================================== 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; Rtimer itimer; Tint icount; }; # 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 (); } |