The following example code demonstrates how to construct the framework for a simple active object which encapsulates a service-provider.
First define and implement the service-provider class. The following code shows the typical features:
class CExampleServiceProvider
{
public:
...
void RequestTheService(TRequestStatus& aStatus);
void CancelTheRequest();
private:
TInt iResult ;
};
Now define and implement the active object which wraps around the service provider. The following code shows the the main features of an active object class.
Provide a constructor.
Provide a RunL()
function to handle the completion
of an asynchronous request.
Provide a DoCancel()
function to implement a
cancellation request.
Provide a RunError()
function to implement
recovery and cleanup if the RunL()
function leaves. Note that this
is not available in ER5.
class CExampleActiveObject : public CActive;
{
public:
CExampleActiveObject(CExampleServiceProvider* aServiceProvider);
~CExampleActiveObject;
void IssueRequest();
private:
void DoCancel();
void RunL();
TInt RunError(TInt aError);
private:
CExampleServiceProvider* iServiceProvider ;
};
When the class codes a DoCancel()
then the destructor
must call the Cancel()
member function of the active
object.
The following code shows the typical elements required when constructing an active object.
CExampleActiveObject::CExampleActiveObject(CExampleServiceProvider* aServiceProvider) : CActive(EPriorityStandard)
{
iServiceProvider = aServiceProvider; // Store pointer to service provider
CActiveScheduler::Add(this) ; // add to active scheduler
}
Set the active object’s priority using one of the
CActive::Tpriority
enumeration values.
Retain a handle to the required service provider, so that request functions can pass on a request to the asynchronous service provider.
Use add()
to add the active object to the active
scheduler, in order to ensure that its requests are handled.
In practice there are many variations on this basic construction theme.
Most active objects set the priority within the constructor and
this is almost always the EPriorityStandard
or zero value. In some
cases, the choice of priority value is decided by the caller or by the
constructor of a class further derived from this one.
In many situations, the service provider is constructed by the
active object itself, instead of being passed in. Often this is done as part of
a two stage construction process. For example, the CTimer
active
object has a simple constructor and a function ConstructL()
which
completes the construction of the object:
CTimer::CTimer(TInt aPriority)
: CActive(aPriority)
{
}
void CTimer::ConstructL()
{
TInt r=iTimer.CreateLocal();
if (r!=KErrNone)
{
User::Leave(r);
}
}