[Cover] [Previous Section] [Next Section] [Index]

Current chapter: Doing More with HDML
Section 15 out of 67 total sections , Section 2 out of 7 sections in this chapter


Using activities to structure your service's interface

HDML provides the concept of activities to help you structure your HDML service. Specifically, activities help you do the following:

Activities correspond to tasks the user wants to carry out; each activity consists of one or more steps. An HDML service can provide multiple activities to its users. For example, an email service could provide activities such as "Create a New Message" and "View Inbox". The "Create a New Message" activity might include steps to choose an e-mail address, enter a subject, and enter the message body.

Figure 2-1 provides a conceptual overview of services and activities.

FIGURE  2-1.     Services and activities

The HDML examples in Chapter 1 demonstrate simple individual activities, each of which consists of a single linear series of steps (cards). However, many services need to provide more complex activities, which contain nested activities or "subactivities." For example, suppose you are implementing the inbox portion of an email service. The overall activity that a user accomplishes with an email inbox is viewing mail. A nested activity is reading an individual piece of mail. In some cases, activities are nested several levels deep. For example, responding to a message could be a nested activity within the viewing mail activity.

When you design an HDML service, you should use an approach similar to the "top-down" design approach popularized by structured programming languages. Start with general activities and then divide them into progressively smaller subactivities. Continue until you have divided the subactivities into steps. Structuring your service this way yields a tremendous advantage: when you code it in HDML, many of the trickier aspects of HDML, such as navigation and variable scoping, virtually take care of themselves. If you use activities correctly, your application's user interface will be clean and intuitive.



Implementing activities in HDML

Chapter 1 provides examples that use the GO and PREV task types to navigate from card to card within an activity. To navigate between activities, you use the following task types.

Task type  Description 
GOSUB  

Requests a card, spawning a nested activity (pushes the nested activity onto the history stack) 

RETURN  

Returns to the activity that invoked the current activity (pops the current activity off history stack) 

CANCEL  

There are some special options that you can use with these task types. These options are discussed later in this chapter.


IMPORTANT     Although the difference between GO and GOSUB appears subtle, it is important. When you request a card (URL) with GO, you are including it in the current activity. When you request a card with GOSUB, you are effectively starting a new, nested activity.

To implement an activity in HDML follow these general guidelines:


Example

Suppose you want to provide a simple stock market data service that allows the user to get either market indices or individual stock quotes. Figure 2-2 graphically represents the activities and tasks that the service provides.

FIGURE  2-2.     Activities and steps for a simple stock market data service

Figure 2-3 depicts how you could implement the "view quote" activity.

FIGURE  2-3.     Implementation of a stock market "view quote" activity

The navigation model in the example operates as follows. When the user chooses the Quotes item, this invokes a GOSUB task, which starts a nested activity and displays the entersymbol card. If the user decides not to enter a stock symbol, he or she can simply press the PREV key, which exits the activity and returns back to the menu. By default, pressing PREV in the first card of an activity returns to the calling activity.

After viewing a quote, the user can press the ACCEPT key to pop out of the activity and return to the menu. Alternatively, the user can press the PREV key to return to the entersymbol card and enter another stock symbol.

Note that there is no particular correspondence between activities and HDML decks. A deck can contain multiple activities and an activity can span multiple decks. For example, in Figure 2-3, the menu.hdml deck contains cards in two different activities.



Activities and the history stack

Chapter 1 describes how the phone maintains a history stack of the cards the user visits. That is a simplification of what the phone does: the phone actually maintains a history stack of visited activities and the cards the user visits within those activities. Each time the user navigates to a nested activity, the phone pushes the current activity onto the history stack. When the phone pushes an activity on to the stack, it maintains the entire user interface state of the activity, including its variable values and the cards the user has visited in it. When the user navigates from a nested activity back to the activity that called it, the phone pops the nested activity off the stack, restoring the calling activity (and its user interface state) to the top of the stack.

Figure 2-4 illustrates the state of the history stack at each stage of the interface described in the previous section.

FIGURE  2-4.     History stack for sample stock market service

Note that when the user returns to the top level card, the item he or she chooses is still chosen. This is because the phone has preserved the state of the activity, including the value of the choice key (the ch variable in this example).

Of course, after the user has backed up and the phone has popped an activity off the stack, the activity's user interface state is lost. For example, if the user returns the menu (the first card in the figure) and subsequently navigates forward to the "Enter Symbol" card, the variable in the "Enter Symbol" card will no longer be set.


Another example

Figure 2-5 illustrates an example email service that nests activities several levels deep. The service is implemented with separate HDML decks (shown on the left). Note that the card that displays the email message does not need to specify a RETURN task. The default task for the ACCEPT key is to execute a PREV task (request the previous card in the history). Because the previous card is in the calling activity, the phone returns to the calling activity.

FIGURE  2-5.     Email service with activities nested to several levels



Activities and variable scoping

The scope of an HDML variable is an activity. An activity can include many decks; any deck in an activity can reference variables in any other deck in the activity. Until the user invokes a destination that uses the GOSUB task, the variables remain in scope.

For example, the following HDML defines two decks within the same activity, the first deck defines an action that uses the GO task to request the second deck. Note how the second deck uses variables set in the first deck (both explicitly and by user input). The interface is depicted in Figure 2-6.

FIGURE  2-6.     Variables used in an activity that spans multiple decks

The phone maintains the variables for each activity separately. If an activity and the activity that invokes it have a variable with the same name, the variables do not collide--they are completely independent of each other. For example, in the following code, Activity A initialize the value of var to 10 and then displays it. It allows the user to navigate to Activity B, which also displays a variable named var. Because var is not set in Activity B, it appears blank.

FIGURE  2-7.     Activities containing a variable with the same name

There are ways to pass variable values between activities. For more information see Passing information between activities.



Specifying navigation between activities

There are several ways a nested activity can allow a user to return to a calling activity:

By default each of these returns the user to the card in the calling activity that invoked the nested activity. For example, the following HDML defines an activity that calls a nested activity. As shown in Figure 2-8, if the user presses ACCEPT, PREV, or SOFT1, the phone returns to the invoking card in the calling activity.

FIGURE  2-8.     Navigation between activities

In some cases, you might not want to return the user to the card in the calling activity that invoked a nested activity. For example, if the card provides a list which the nested activity modifies, returning directly to it would be undesirable--because the list would be obsolete.

Fortunately, HDML allows you to change the default navigation from a nested activity back to the activity that called it. You can change the navigation by specifying the following task options for the GOSUB task that navigates to the nested activity:

For example, you could rewrite the example above so that when the user presses SOFT1 (the key labelled DEL), the phone returns to a "inbox empty" card instead of the same inbox card.

FIGURE  2-9.     Navigation using the NEXT option of the GOSUB task

Note that the NEXT option effectively performs a GO task; the card it specifies is in the same activity as the card that contains the NEXT option.

You can override a calling activity's NEXT and CANCEL options by specifying the DEST option for the RETURN and CANCEL tasks of the nested activity. However, the FRIEND option in the GOSUB task of the calling activity must be set to TRUE for it to work. This is a security precaution that prevents an "unfriendly" subactivity from directly accessing a card in the calling activity.



Passing information between activities

HDML provides several mechanisms for passing information between activities:

The following sections describe these methods of passing variable information in more detail.


Passing variables to a nested activity

The VARS option passes variables by name to nested activities. The syntax for the VARS option is:

The nested activity uses the variable names to reference variables that the calling activity specifies in the VARS option; it must know the names of the variables in order to use them. For example, the following HDML deck includes an activity that passes several variables to a nested activity. The nested activity displays the variable values in a simple display card.

FIGURE  2-10.     Variables passed to a subactivity

Note that when you set a variable's value, you must escape the value using URL escaping conventions. For example, the code above uses the plus sign (+) to specify a space in the var2 variable value.


IMPORTANT     When a nested activity changes the value of the variables passed to it, it does not affect the variables in the calling activity.


Returning values to a calling activity

To accept return values from a nested activity, you specify the RECEIVE task option in the calling activity and the RETVALS task option in the nested activity. The RECEIVE option specifies a semicolon-delimited list of variables to receive values; the RETVALS option specifies a semicolon-delimited list of values. When the nested activity returns, the phone uses the values in the RETVALS list to set the RECEIVE variables.

The phone assigns the return values by position. That is, it assigns each value in the RETVALS list to the variable that occupies the corresponding position in the RECEIVE list. If the RETVALS list doesn't provide a corresponding value for a variable in the RECEIVE list, the phone clears the variable, so it has no value. Note that this contrasts with the way the phone handles variables in the VARS option--which it passes by name.

The table below provides some examples of how the phone sets variables in the RECEIVE list.

RECEIVE option of calling activity  RETVALS option of nested activity  Variable values after nested activity returns 
RECEIVE=var1;var2;var3  
RETVALS=a;b;c  

var1: a 

var2: b 

var3: c 

RECEIVE=var1;var2  
RETVALS=a;b;c  

var1: a 

var2: b 

RECEIVE=var1;var2;var3  
RETVALS=a;;b  

var1: a 

var2: (no value) 

var3: b 

RECEIVE=var1;var2;var3  
RETVALS=;;b  

var1: (no value) 

var2: (no value) 

var3: b 

RECEIVE=var1;var2;var3  
RETVALS=a;b  

var1: a 

var2: b 

var3: (no value) 


Example: HDML forms entry

The following HDML deck includes an activity that calls two nested activities to change the variables it displays. The interface (depicted in Figure 2-11) is similar to that used in many common HDML services (such as UP.Mail and UP.Organizer) to provide lists of settings that the user can change. It is the recommended method for implementing "forms" in HDML.

FIGURE  2-11.     Nested activities that return values


Clearing variables in a calling activity

You can use a nested activity to clear all the variables in an activity. To do this, you must write the nested and the calling activities so that:

The default for the FRIEND task option is FALSE. This is a security precaution that prevents malicious activities from resetting all of a calling activity's variables. Always make sure an activity is calling a "friendly" activity when you set the FRIEND option to TRUE.

Suppose you want to modify the interface depicted in Figure 2-11 so that the user can clear the both the Name and Alias fields by pressing SOFT1. To do this, you add a no-display card that uses the clear option. The added code is shown in bold below. The interface is shown in Figure 2-12.

FIGURE  2-12.     Clearing variables in a calling activity

You can specify both the CLEAR option and the RETVALS option for the CANCEL or RETURN tasks of a nested activity: the phone first clears the variables of the calling activity and then sets any of the variables specified in the calling activity's RECEIVE option.


[Cover] [Previous Section] [Next Section] [Index]

Current chapter: Doing More with HDML
Section 15 out of 67 total sections , Section 2 out of 7 sections in this chapter


Copyright © 1999, Unwired Planet, Inc. All rights reserved.