Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Symbian OS Explained - Effective C++ Programming For Smartphones (2005) [eng].pdf
Скачиваний:
60
Добавлен:
16.08.2013
Размер:
2.62 Mб
Скачать

124

EVENT-DRIVEN MULTITASKING USING ACTIVE OBJECTS

the event handler and additional code for construction, destruction, error-handling and cancellation. However, application code requires some understanding of active objects and requires implementation of active object code that is incidental to the purpose of the application. In addition, many other operating systems do not encapsulate event handling in the same way. This means that Symbian OS code is not directly portable to other operating systems.

For this reason, Symbian OS provides frameworks to hide active object code from high-level application code by defining handler interfaces (often mixin classes as described in Chapter 1) which a client implements. The frameworks hide the active objects, implementing initialization, cleanup and error handling, and performing generic event processing in the RunL() method. In RunL() the framework calls methods on the client-implemented interface to respond to the completed event. The appropriate client object receives the call, having ”registered” with the framework by passing a reference or pointer to its implementation of the interface. The one rule the client should be aware of is that the interface methods should be implemented to complete quickly so that the framework can handle other events without delay.

An example of this may be seen when application code runs within the GUI framework (CONE), which uses active objects to handle events associated with user input and system requests such as window redraw requests, originating from the window server. The framework implements the RunL() method to process each event, and calls an appropriate virtual function such as OfferKeyEventL() or HandlePointerEventL() in the associated control. As an application programmer, all you have to do is implement the functions defined by the framework and it takes care of the mechanics of event handling.

Likewise, server code runs inside the Symbian OS system server framework and handles requests from client messages. Server code often implements its own additional set of internal active objects, to make requests to asynchronous service providers while still remaining responsive to incoming client requests. The client–server architecture is discussed in detail in Chapters 11 and 12.

8.7 Summary

Symbian OS makes it very easy to write event-driven code without getting too involved in the implementation of the active objects which handle the events. This chapter set out to explain the basics of how active objects work, why you should prefer them to threads for multitasking and how to implement a basic active object class. If you are likely to write server code, implement an asynchronous service provider or perform more advanced GUI programming, you will probably be interested in the

SUMMARY

125

next chapter, which goes deeper into the responsibilities and roles of the main components – active objects, asynchronous service providers and the active scheduler.

This chapter explained that:

Active objects were designed for lightweight, responsive, powerefficient event-handling and are used by most applications and servers, generally in a single thread.

Active objects are scheduled cooperatively in a single thread and,

in

consequence, are easy to program because there is

no need

to

use synchronization primitives to prevent concurrent

access to

shared resources.

The kernel schedules threads pre-emptively but these are not generally used for event-driven multitasking.

The active object framework on Symbian OS has a modular design that decouples event completion processing, performed by the active scheduler, from individual event handling, performed by active objects.

The constructor of the active object class should set its priority and add it to the active scheduler. Any initialization required by the asynchronous service provider should be performed in a second-phase constructor.

Active objects encapsulate an asynchronous service provider and the event handling necessary when a request to that service provider completes.

Active objects provide request initiation functions. These usually conform to a pattern: performing a check for no previous outstanding requests, submitting the request with its iStatus member variable as a parameter, and setting the state of the active object to indicate that a request has been issued.

Event handling is performed by implementing the pure virtual RunL() method defined in the CActive base class; RunL() is called by the active scheduler some time after the request completes.

Because active objects cannot pre-empt each other, RunL() should complete as quickly as possible so that other active object events can be handled without delay.

The pure virtual DoCancel() method must also be implemented by deriving classes and should call an appropriate method on the asynchronous service provider to cancel the request.

126

EVENT-DRIVEN MULTITASKING USING ACTIVE OBJECTS

The default ”do nothing” implementation of the virtual RunError() method on the base class should be overridden if the derived class can reasonably handle leaves which occur within its RunL() function.

Symbian OS uses framework code to conceal the active object idiom. For example, the GUI framework dispatches incoming events to be handled by functions implemented by an associated control, which may be extended by individual applications as required.

The next chapter looks ”under the hood” at active objects, discusses the responsibilities of active objects, asynchronous service providers and the active scheduler, and illustrates best practice when writing and using active objects. Chapter 10 has more information about Symbian OS threads and processes, while Chapters 11 and 12 build on an understanding of active objects, threads and processes, to describe the Symbian OS client–server architecture in detail.