How to Use Avkon ViewSwitching Architecture
This subsection will show how you would go about implementing an Avkon View-Switching Architecture application. Figure 4-1 illustrates the Series 60 classes that a view-switching application must derive from. It is important to note that, when using this architecture, the CAknViewAppUi and CAknView classes must be used in conjunction with one another. Each Avkon view derives from CAkn View and must provide an ld() function so that it can be identified by the system. It must also implement the DoActivateL() and Do Deactivate L() function. Additionally, it should implement the andleForegroundEventL(), HandleCommandl_() and HandleStatusPaneSizeChange() functions to handle various events. The class declaration for CShapeDrawerListView shows a typical Avkon view:
class CShapeDrawerListView: public CAknView public: // constructors and destructor static CShapeDrawerListView* NewL(); static CShapeDrawerListView* NewLC(); ~CShapeDrawerListView();
CShapeDrawerAppUi& GetAppUiQ;
private: // from CAknView TUid ld() const;
void HandleCommandL(Tlnt aCommand); CShapeDrawerListView();
void DoActivateL( const TVwsViewld& aPrevViewld, TUid aCustomMessageld, const TDesC8& aCustomMessage);
void DoDeactivate();
private: // constructors void ConstructL();
private: // data CShapeDrawerListViewContainer* ¡Container;
DoActivatel_() is called by the View Server when a client requests that your view is activated. Its purpose is to instantiate and display the control that renders the view. As the function prototype above implies, it is possible to pass customized messages to the View being activated. This information could be used, for example, to prepopulate the view with data specified in the message. The passing of these message parameters is entirely optional.
Be aware that DoActivateL() may be called multiple times prior to DoDeactivateL(), and therefore your implementation must not assume that the view's control has not already been created and displayed. Such multiple calls can occur when a client requests reactivation of the view with some additional message parameters. Your DoActivateL() call must be prepared to handle this eventuality.
DoDeactivate() is called when your Avkon view is to be deactivated. This function is responsible for destroying its control. Your view will be deactivated when your application exits, or when another view in the same application is activated. This function must not leave.
HandleForegroundEventLO will be called only while your Avkon view is active (in other words, in-between calls to DoActivateL() and DoDeactivateO). When your view comes to the foreground, it will receive HandleForegroundEventL(ETrue). When your view is removed from the foreground, it will receive HandleForegroundEventL(EFalse). This function will be called only when the foreground state actually changes. Note that it may be called a number of times during your view's active period, as the owning application comes and goes from the foreground. You may want to use this method for setting focus or for controlling screen updates.
HandleCommandLO will be called when the view's menu generates a command, and
HandleStatusPaneSizeChange() will be called when the client rectangle size changes due to a change in the status
This is the typical order of events that an Avkon view will receive over an active period. Activating a new Avkon view:
1. DoActivateL()
2. HandleForegroundEventL(ETrue)
Deactivating an Avkon view:
1. HandleForegroundEventL(EFalse)
2. DoDeactivateO
As previously stated, the pair of view-activation function calls may happen a number of times during a view's active period.
Typically, each Avkon view will require its own menu options. It is easy to give each Avkon view its own unique set by simply associating the view with a resource. Therefore, to let an Avkon view define its own soft keys and/or menu, create an AVKON_VIEWresource in your resource (.TSS) file, then pass the resource ID into the view's BaseConstructl_() function. Again, further detail on resource files and structures can be found in Chapter 5.
The view resource for ShapeDrawer is shown here:
RESOURCE AVKON_VIEW r_shapedrawer_graphicview menubar= r_shapedrawer_menubar1;
The menubar r_shapedrawer_menubar1 is also defined in the resource file and specifies the menu options. Note that CBA (or Command Button Area) is an alternative name sometimes used for soft keys—this comes from a Symbian OS convention. R_AVKON_SOFTKEYS_OPTIONS_BACK is a standard soft key definition (defined inavkon.rsg) and sets the soft keys to Options and Back. Another definition is R_AVKON_SOFTKEYS_OPTIONS_EXIT, which sets the soft keys to Options and Exit.
The code to associate this resource with its Avkon view would be:
void CShapeDrawerGraphicView::ConstructL() BaseConstructL(R_SHAPEDRAWER_GRAPHICVIEW);
All of the Avkon views in your application would normally be constructed in the AppUi object's ConstructL() method. They are registered with the View Server using AddViewL(), and finally the initial view is activated by setting it as the default view. The following code from the ShapeDrawer application demonstrates the AppUi as the owner of two Avkon views, CShapeDrawerGraphicViewand CShapeDrawerListView, and shows the required initialization process.
void CShapeDrawerAppUi::ConstructL() BaseConstructLQ;
iViewl = CShapeDrawerGraphicView::NewL(iDocument); AddViewL(iViewl); // transfer ownership
¡View2 = CShapeDrawerl_istView::NewL(iDocument); AddViewL(iView2); // transfer ownership
SetDefaultViewL(*iView1);
As mentioned before, Avkon views have no innate drawing capabilities. Therefore each Avkon view will typically own a Container class that derives from CCoeControl. An instance of this will therefore be present in the view:
class CShapeDrawerGraphicView: public CAknView private: // data
CShapeDrawerGraphicViewContainer* ¡Container; // what this view will display
The currently activated view receives commands via its HandleCommandL() method. This is where soft key-generated commands and commands generated from the user interacting with the view's associated menu are handled. For example:
void CShapeDrawerListView::HandleCommandL(Tlnt aCommand) switch (aCommand)
case EAknSoftkeyBack: {
AppUi()->HandleCommandl_(EEikCmdExit);
case EShapeDrawerRemoveSelectedltem: {
¡Container->RemoveCurrentltemL();
default: {
AppUi()->HandleCommandL(aCommand);
Note that commands that are not handled by the Avkon view are passed on to the AppUi. In theShapeDrawer example, view-switching commands are passed to the AppUi:
void CShapeDrawerAppUi::HandleCommandL(Tlnt aCommand) switch (aCommand)
case EShapeDrawerSwitchToListView: {
TUid viewld;
viewld.iUid = EShapeDrawerListViewld; ActivateLocalViewL(viewld);
case EShapeDrawerSwitchToGraphicView: {
TUid viewld;
viewld.iUid = EShapeDrawerGraphicViewld; ActivateLocalViewL(viewld);
default:
User::Panic(KShapeDrawerPanicName, EShapeDrawerUnknownCommand); break;
Local view switching, or switching to a view that is owned by your application, is performed by referring to the UID of the Avkon view that you want to switch to.
In order to perform an external view switch, slightly more information is required. Call one of the CCoeAppUi::ActivateViewL() functions, providing aTVWsViewld containing the target application's UID and the target view UID. The following code excerpt demonstrates this:
const TUid KPhoneBookUid = { 0x101f4cce }; //from PbkUID.h const TUid KPhoneBookContactViewUid = { 1 };
ActivateViewL(TVwsViewld(KPhoneBookUid, KPhoneBookContactsViewUid));
As you can see, the mechanism for accessing an external view is similar to that for accessing local views. See thellsinq Standard Application Views section in Chapter 12 for more detailed information on external view switching.
All view-switching applications should publish their application and view UIDs by exporting them to a header file, so that they can be identified by other applications. Of course, if the application holds views that should not be accessible by other applications, then their publication should be withheld.
Choosing the Appropriate Application Architecture
When to Use Avkon View-Switching Architecture
Although view switching operates on a very simple set of rules, it provides a new way of thinking about application design and interapplication interaction. View switching allows applications to make better use of each other, in a way that makes navigation between applications seamless for the user.
Consider how users had to navigate between applications prior to the advent of view switching: Imagine that a user had just received an email from a new colleague. Apart from reading the message, it is plausible that they would want to add this new colleague to their contacts list. Without view switching, it would be necessary for them to manually start up the contacts application, manually navigate to the contact entry view, and then to enter the colleague's details. But with Avkon View-Switching Architecture, it is possible for the email application to provide a direct switch to the contact entry view of the contact application, and also to populate the view with some initial contact details.
The above scenario suggests using a view switch to access the contacts application in order to enter contact data, but this is not the only way to achieve this type of functionality—Series 60 provides many APIs to manipulate data in standard applications by accessing their application engine components directly. Chapter 12 gives more information on this alternative approach.
NOTE
With this new architecture, programming this view switch into an application is trivial—you only have to request view activation from the View Server, passing in the application UID, the view UID and a package buffer containing any other relevant information. The View Server will then automatically start up the contacts application (if not already started) and switch directly to the appropriate view. Switching to standard applications is covered in more detail in Chapter 12.
This mechanism allows applications to smoothly interoperate, and in most cases, view switching is the best architecture choice. However, you need to be aware of its limitations. For example, the view-switching scheme has no built-in way to preserve the context of a view switch. That is, it does not provide a standard mechanism for navigating back to the previously active view (think of the "back" button on a Web browser). These limitations mean that if an application executes a remote view switch, the user has no visual clue as to how this view was reached. However, DoActivateL() does receive an identifier for the previously active view, so it is possible to develop your own "back" button functionality.
Another consideration is that you may wish to prevent external applications from being able to switch to certain views within your application. The View Server architecture offers no way to explicitly forbid the external activation of a view. There are workarounds, however. For example, you can make it very difficult to access views by not publishing their UIDs. What is important to understand is that, if it is absolutely necessary for some views to be unreachable by external applications, then the View Server cannot accommodate this requirement, and it will be necessary to use a different Ul architecture.
When to Use Traditional Symbian OS Control-Based Architecture
In general, the default architecture for your Series 60 application would probably be the Avkon View-Switching Architecture.
However, there are reasons why you might prefer the Traditional Symbian OS Control-Based design:
• Your application requires only one view, and it is unlikely that other applications will want to perform an external switch to it. In this case, you would not get anything out of the Avkon View-Switching scheme; it would just be unnecessary overhead.
• Your application has Ul controls whose privacy must be guaranteed. If you are using the Avkon View-Switching Architecture, you can make it very difficult for other applications to switch to a view in your application by not publishing its ID, but there are no guarantees of privacy.
• You are porting an application from a different Symbian OS platform to Series 60. In this case, you may wish to simply stick with the existing Ul architecture, especially if it appears unlikely that other applications would want to perform external switches to any views within the application.
When to Use Dialog-Based Architecture
This approach is very suitable to applications whose Ul controls are made up of a straightforward arrangement of traditional OS controls, such as data entry or settings applications. Controls can be defined in resource files, with the dialog handling layout and drawing automatically—this is much easier than implementing custom drawing behavior.
The other consideration is the application's navigation requirements from screen to screen. The application is a candidate for this "dialog-based" approach if and only If there are no cyclical navigation paths among the application's views. Figure 4-6, along with the discussion that follows, will clarify this point.
- Figure 4-6. Screen navigation in a Dialog-Based application.
Each box in the figure represents a different view in an application, and each number represents a different dialog class. Classes 1 and 3 are multipage dialogs—the lettered variations represent their different pages. The arrows depict the screen navigation possibilities.
The rule is that, in navigating downward in the hierarchy (for example, from 1a to 3a), you must return along the same path when navigating back upward. Therefore, navigating from 1a to 3a to 1b is disallowed. If this were allowed, then the user could navigate in a big circle. Each cycle (1a-3a-1b-1a) would instantiate two new dialog objects (dialog 1 creates an instance of dialog 3, in navigating from 1 a to 3a, and dialog 3 creates another instance of dialog 1 in navigating back to 1 b), while at the same time still holding objects instantiated in past cycles in memory. So, apart from having no logical benefit, this cyclical navigation is a liability in terms of its undue memory consumption.
If you are considering using dialogs as your main view, then note that their navigation paths are limited, as well as their layout possibilities.
Post a comment