This article was originally prepared by Yang. If you need to reselect the article, please indicate the source. Thank you!
In the previous section, we have roughly understood the basic concepts of activity objects. To use the activity object mechanism, we need to use activity objects, activity schedulers, and asynchronous functions. To use an asynchronous function, followApplication> activity Object> activity scheduler> asynchronous Function. Next, we will start to use the activity objects.
1. Create an activity Scheduler
We know that the active scheduler serves as a bridge between an application and an asynchronous function. The application uses the active object to intercept the "completed" message returned by the asynchronous function through the active scheduler, and notify the application as an event.
Using Carbide C ++ 1.3, the console program generated by the template wizard automatically generates code for creating the activity Scheduler for us:
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); CActiveScheduler::Install(scheduler);
After the cactivesched: Install () method is called, the internal code will assign the scheduler pointer to the static pointer inside the CActiveScheduler class, and the subsequent code will be able to conveniently use the static method of the CActiveScheduler class, for example:
IMPORT_C static void Add(CActive* aActive); IMPORT_C static void Start(); IMPORT_C static void Stop();
- Add () method: Add the activity object to the activity Scheduler for registration.
- Start () method: Start the activity scheduler, which starts to wait cyclically for the notification message returned by the asynchronous function.
- Stop () method: Stop the activity Scheduler
2. Create activity objects
1. The created activity object must be derived from the CActive class, And the CActive class has prepared the iStatus member variable for us:
public: TRequestStatus iStatus;private: TBool iActive;
Another member variable, iActive, plays an identity role and proves that the activity object has requested an asynchronous function, for example:
RTimer::After(iStatus, 1000000);SetActive();
The SetActive () method is used as the basic CActive method. In fact, iActive = ETrue; is used to identify the activity object that has called the asynchronous function.Therefore, as long as an asynchronous function is called, the code that calls the asynchronous function should be followed by the code that calls the SetActive () method.
2. Two virtual methods must be inherited:
virtual void DoCancel() =0; virtual void RunL() =0;
- RunL Method: After the activity scheduler receives the "finish" message returned by the asynchronous function, it traverses all the activity objects registered with it. If the iActive of the activity object is ETrue and iStatus! = KRequestPending: Call the RunL method of the activity object and set iActive to EFalse to prevent the activity object from being called in the next round-robin.
Here, the name "RunL" may lead to ambiguity for many people. When I first came into contact, I always thought it was similar to the run method of the Runnable interface in j21. In fact, it is more appropriate to change "RunL" to "policyrequestcompletel" here.
Again, when an asynchronous function is called, The TRequestStatus and status parameters are passed in reference mode, for example:
IMPORT_C void After(TRequestStatus &aStatus, TTimeIntervalMicroSeconds32 anInterval);
So the asynchronous function can change the real parameter of status, that is, change the class member iStatus of the activity object.
- DoCancel () method: The base class CActive has the Cancel () method for canceling asynchronous functions. After Cancel () is called, the activity object will pass DoCancel () the method notifies the application to cancel the method, such as deleting objects and revoking pointers. Note: To terminate an activity object in an application, use the Cancel () method instead of the DoCancel () method.
3. constructors with priority for activity objects:
The prototype of the base class CActive constructor is as follows:
protected: IMPORT_C CActive(TInt aPriority);
A priority enumeration value will be input here. The enumerated value is as follows:
/**Defines standard priorities for active objects.*/enum TPriority { /** A low priority, useful for active objects representing background processing. */ EPriorityIdle=-100, /** A priority higher than EPriorityIdle but lower than EPriorityStandard. */ EPriorityLow=-20, /** Most active objects will have this priority. */ EPriorityStandard=0, /** A priority higher than EPriorityStandard; useful for active objects handling user input. */ EPriorityUserInput=10, /** A priority higher than EPriorityUserInput. */ EPriorityHigh=20, };
When you call the cactivesched: Add method to register an activity object, the activity scheduler sorts the activity objects according to their priorities and inserts or adds them to the activity object set. When multiple asynchronous function messages are returned at the same time (multiple iStatus are not KRequestPending at the same time ), when an activity object scheduler training set, it always finds the activity object with a higher priority and calls its RunL method.
However, in general, EPriorityStandard is passed in the constructor.
3. pseudocode of the Start method of the activity Scheduler
Through the above two analyses, we can simulate the CActiveScheduler: Start method:
Void CActiveScheduler: Start () {for (;) {// suspend the thread until the asynchronous function message is returned. // note: the active scheduler and application are not in the same thread, therefore, the application will not block User: WaitForAnyRequest (); // If the asynchronous function and the main program are in different threads, RThread: WaitForAnyRequest (); // when a message is returned, the thread will wake up. // in descending order of priority, the thread will detect every active object in the scheduler set (;;) {// call the first completed activity object event processing function, if (activeObject-> IsActive () & activeObject-> iStatus! = KRequestPending) {// locate an activity object that is ready to process the event // reset the iActive status to indicate that it is no longer in the active status activeObject-> iActive = EFalse; // call the event processing function TRAPD (err, activeObject-> RunL () of the activity object in the TRAP; if (err! = KErrNone) {// if an exception occurs, call the RunError method err = activeObject-> RunError (); if (err! = KErrNone) {Error (err) ;}} break ;}}}}
4. Examples of using activity objects
Click here to download the source code
In this example, a console program is started and the RTimer timer of the asynchronous service class is used to display the accumulated number on the screen every second. The effect is as follows:
V. Summary
In this section, we have a basic understanding of the working mechanism and workflow of the activity scheduler and activity objects. In the next section, we will go deep into the activity objects, understand its working principles and further deepen its understanding of the activity objects.
Vi. References
- Symbian OS Explained valid tive C ++ Programming for Smartphones