USERNAME PASSWORD LOST PASSWORD? REGISTER
"A Complete Mobile Application Development Environment"
Advertisement

Downloads
Documentation
Forums
Blog
Press
Contact Us




Background Processing PDF Print E-mail

Most applications will launch as the primary UI application and run until the user chooses to switch to a different application, at which point they will exit. However, for certain applications it may make sense to switch to the background, rather than exiting. For instance, an MP3 player that is running in the foreground ideally should continue playing music even if the user switches to another application. It should also implement a mechanism whereby the application can be brought back to the foreground; perhaps when the user "relaunches" the application.

Specifying the Basic Behavior ^TOP^

The backgrounding element in the application's manifest file specifies the basic foreground/background behavior of the application. If this element is not present in the manifest file (within the application element), the Launcher assumes that the application always runs only in the foreground. This is equivalent to specifying a backgrounding element value of unsupported:

<backgrounding>unsupported</backgrounding>

The backgrounding element can have one of four values: unsupported, required, supported, or preferred.

unsupported
Indicates that the application or preference panel should only be launched as the primary application.
required
Indicates that the application needs to be left running in the background. The Application Manager always tries to leave these applications running, so they need to be extremely careful with resource usage.
supported
Indicates that the application can be run in either the foreground (as the main UI application) or in the background.
preferred
Indicates that the application prefers to run in the background as long as resources are available, but does not require it.

These element values only specify the behavior of your application when it needs to step aside for another application to assume the role of primary UI application; they do not affect how it is intially launched by the Application Server. When the user launches an application from the Launcher, that application becomes the foreground (primary) application, regardless of the backgrounding setting. When another application is programmatically launched, the current application only steps aside (or quits, as appropriate) if the new application is being launched as primary. (See "Launching Another Application" for instructions on launching other applications in this manner.)

The vast majority of applications need more control over just how and when they transition between foreground and background execution. Switching an application from foreground to background (and vice-versa) can be done regardless of the backgrounding element value.

Here is a simple manifest file with the backgrounding element set:


<?xml version="1.0" encoding="UTF-8"?> 
 
<manifest name="com.example.apps.testapp"> 
  <application> 
    <name>Test App</name> 
    <icon>icon.gif</icon> 
Ā Ā Ā Ā <backgrounding>required</backgrounding> 
  </application> 
</manifest> 

Altering the Behavior Programmatically ^TOP^

The backgrounding status of your application is initially determined by the setting of the backgrounding element in the application's manifest file, and for most applications that is sufficient. Once your application is running, however, you can change it with a call to alp_app_set_backgrounding(). This call sends a message to the Application Server to change the application's current "backgrounding setting." This setting affects whether or not the application will be relaunched and left running in the background when it otherwise would receive an exit request (when a new primary application is launched, for example).


NOTE: There are some potential concurrency issues: alp_app_set_backgrounding() could be called and could return all after the Application Server has sent an exit request using the old setting.

alp_app_set_backgrounding() takes as its sole parameter a string that specifies the new desired setting. The appmgr.h header file (in the Hiker Application Framework) defines contants for the accepted string values. These constants correspond to the values you can supply for the backgrounding element in the manifest file, and are:

  • ALP_APP_PROP_BG_UNSUPPORTED
  • ALP_APP_PROP_BG_REQUIRED
  • ALP_APP_PROP_BG_SUPPORTED
  • ALP_APP_PROP_BG_PREFERRED

It is important to note that the alp_app_set_backgrounding() function only changes the backgrounding setting; it does not actually cause your application to be moved from foreground to background or background to foreground.

Background Applications and the Launcher ^TOP^

If an application is running in the background and the user relaunches it from the Launcher, it will be relaunched with an ALP_APP_PRIMARY launch code. If the application has registered a relaunch handler, the relaunch handler will be called instead of alp_main().

Executing in the Background ^TOP^

When you receive the ALP_APP_PRIMARY launch code, you know that you are executing in the foreground. Similarly, the ALP_APP_BACKGROUNDED launch code is the signal that you are executing in the background. Unlike a foreground application, you are not the "primary application" and thus do not have full control of the display. Consequently, when you receive the "backgrounded" launch code you should first hide any UI you may have been displaying. Then, perform the background task. Note that if the background task takes more than 3 seconds1, you need to break it up so that it periodically allows the main event loop to execute; otherwise, the Application Server may decide that you are not responding and forcibly shut your application down.

Most often you will receive the ALP_APP_BACKGROUNDED launch code during a relaunch. If your application had previously been running in the foreground and displaying UI, you'll need to hide your application's UI when relaunching in the background. If, however, you receive ALP_APP_BACKGROUNDED when your application is started for the first time, simply don't draw the application's UI.

You can hide your application's UI like this:


alp_max_dialog_cancel_all(); 
gtk_widget_hide(GTK_WIDGET(main_window)); 
	// main_window is the application's top-level window 

Although a background application doesn't have primary control over the application's UI, that doesn't mean that a background application cannot draw any UI at all. Background applications can display some limited UI (a dialog, for instance), but should do so as little as possible to avoid confusing the user between your background application's UI and the UI of the primary (foreground) application.

Handling the Background to Foreground Transition ^TOP^

If your application is relaunched as the primary application when it previously had been running in the background, simply unhide any previously hidden UI by calling gtk_window_present() and passing it the GtkWindow representing your application's top-level window.

Launching Another Application ^TOP^

The Application Manager's alp_app_launch() function causes the named application to be launched. As a side effect, if the new application is being launched with the ALP_APP_PRIMARY launch code, the Application Server shuts down or moves into the background the calling application, depending upon the application's current "backgrounding setting." Thus, this mechanism can be used by an application to move itself to the background.

The code excerpt in Listing 14.1 shows how to use alp_app_launch() to launch a new application.

Listing 14.1  Programmatically launching another application


char *launch_args[] = { 
	ALP_APP_PRIMARY 
}; 
int launch_arg_count = sizeof(launch_args) / sizeof(char *); 
 
void on_button_clicked(GtkWidget *button, gpointer userdata){ 
	alp_status_t status; 
	 
	status = alp_app_launch("bar:com.example.apps.appb",
		launch_arg_count, launch_args, NULL); 
} 

Note that the launch codes you supply to the new application (here, in the launch_args array) control how the application is launched. If, rather than ALP_APP_PRIMARY, the set of launch codes included ALP_APP_BACKGROUNDED, the new application would be launched in the background and the calling application would continue to run as the primary application.

Multithreading ^TOP^

Most ACCESS Linux Platform applications consist of a single thread of execution. Applications do have the option to spawn additional threads using the glib threads APIs (see http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html for documentation on those APIs).

Inter-Process Communication (IPC) ^TOP^

ALP Abstract IPC ^TOP^

ALP Abstract IPC is a simple interprocess communication (IPC) mechanism included as part of the Hiker Application Framework. It is designed to be independent of the underlying mechanism (such as pipes, sockets, or D-BUS). It provides a simple, easy to use send-and-receive message API that also includes full support for the incremental marshalling and unmarshalling of message data. For efficiency, it minimizes context switches by sending messages directly between processes without passing them through an intermediary process.

The Abstract IPC model is based on a single server process exchanging messages with one or more clients. The server process creates an AlpChannel. Clients connect to the channel and receive an AlpConnection pointer that they can use to send messages to and receive messages from the server.

The Abstract IPC mechanism itself doesn't need to know the format of the messages being exchanged. The format of those messages is completely up to the server and channel clients.

Communication can be synchronous or asynchronous. When done asynchronously, processes receive messages via a callback mechanism that works through the gLib main loop.

The Abstract IPC mechanism is a flavor of IPC (inter-process communication) mechanism that provides simple abstract methods for peer-to-peer IPC, chiefly for message transfer between the participating peers. Its primary features include:

  • Communication between peer processes through message passing
  • Marshalling and unmarshalling of message contents
  • Getting user, group, and peer ID information
  • Non-blocking (asynchronous) and blocking (synchronous) sending of messages
  • Blocking (synchronous) and non-blocking (asynchronous) receiving of messages
  • Storing and retrieving channel-specific information
  • Storing and retrieving connection-specific Information

The messages that are exchanged between peers can be made up of the following data types:

  • Integer (int32)
  • Unsigned integer (uint32)
  • Float (float)
  • Null-terminated string (string)
  • Array of bytes (byte_array)

Using the Abstract IPC Mechanism

The basic steps to sending a message from one process to another using the Abstract IPC mechanism are:

  1. The server creates a channel.

    In order to use the Abstract IPC mechanism, the server process must first create a channel using the function alp_ipc_channel_create(). This function returns a pointer to the channel.

    Note that this function should only be called by the server for the named channel.

    When finished with the channel, the process that makes the call (that is, the server for the channel) is responsible for cleaning up the channel by calling alp_ipc_channel_destroy().

  2. The server registers for channel connect and disconnect callbacks.

    alp_ipc_channel_register_connect_callback() registers a callback within the server process that is called whenever a client connects. Note that only one connect callback function can be registered at any time. If a second call to register a callback is made, it replaces the first call. Passing NULL as the callback function deletes the callback. If the server process is going to send messages to the connecting client , it must store the AlpConnection pointer it receives via the callback when the client connects.

    alp_ipc_channel_register_disconnect_callback() similarly registers a server process callback that is called whenever a client either disconnects or exits without disconnecting. As with the connect callback, only one disconnect callback function can be registered at a time.

    To receive a callback whenever a message is received from a client, call alp_ipc_connection_register_receive_callback(). Again, only one "message received" callback can be registered at a time for a given channel. When a message is received, the callback is passed pointers to the connection and the message, along with a gpointer supplied when the callback is registered. This cbData pointer allows you to pass application-specific data from the callback registration to its invocation.

    The message ID and format are immediately available to the callback. The other data in the message must be unpacked using the various alp_ipc_message_unpack_...() functions. Note that the originator of the message will take care of deleting the AlpMessage structure.

  3. Clients request a connection to the channel.

    Once the channel has been created, client processes (multiple clients can connect to a given channel) request a connection to it. There are two ways of establishing the connection: synchronously or asynchronously.

    To establish a synchronous (blocking) connection to the channel, clients call alp_ipc_channel_connect_synch(). The function blocks until the connection is ready or until the number of milliseconds specified by the timeout parameter have elapsed. Callers pass in an AlpConnection** to receive a pointer to the new connection.

    To establish an asynchronous connection to the channel, clients call the function alp_ipc_channel_connect(). This function does not block; rather, a callback is invoked when the connection is ready.

    Regardless of how the caller establishes a connection (synchronously or asynchronously), when done with it the caller is responsible for destroying the connection with alp_ipc_channel_disconnect().

  4. The client registers for server activity callbacks (message received, server disconnected).

    To receive a callback whenever a message is received, clients, like servers, call alp_ipc_connection_register_receive_callback(). Note that only one "message received" callback can be registered at a time for a given channel. When a message is received, the callback is passed pointers to the connection and the message, along with a gpointer supplied when the callback is registered. This cbData pointer allows you to pass application-specific data from the callback registration to its invocation.

    The message ID and format are immediately available to the callback. The other data in the message must be unpacked using the various alp_ipc_message_unpack_...() functions.

    In order to be notified when the server disconnects, either by destroying the channel or by exiting, clients call alp_ipc_connection_register_disconnect_callback(). Again, only one disconnect callback function can be registered at any time. If a second call to register a callback is made, it replaces the first call. Pass NULL as the callback function to delete the callback.

  5. One side creates an empty message.

    The message sender needs to create the message before moving on to the stage of message marshalling and sending. To create a message, use the function alp_ipc_message_create() to allocate an AlpMessage structure.

  6. The sender packs the AlpMessage structure with the contents of the message.

    Begin the process by calling alp_ipc_message_pack_start(). This function sets the message ID and prepares internal buffers for packing the message data. Any old message information (which would be present only if you are reusing an AlpMessage structure) is discarded.

    Next, make zero or more calls to alp_ipc_message_pack_type(), where type is the value type being added to the message (such as int32 or string).

    Finally, call alp_ipc_message_pack_end().

    If you are packing a message that is a response to a previously sent message, call alp_ipc_response_pack_start() instead of alp_ipc_message_pack_start(), then pack and end the message as outlined above.

  7. Send the message.

    Once the message packing is completed, the message is ready to be sent. It can be sent either synchronously (blocking; the function waits for a response), or asynchronously (non-blocking). To send the message and await a response, call alp_ipc_connection_send_with_response(). Otherwise, send it using alp_ipc_connection_send().

    Note that if you send the message synchronously, you are responsible for deleting the returned AlpMessage with alp_ipc_message_destroy() when finished.

  8. Receive a message.

    The message that is sent over a connection has to be received at the other end of the connection, where it is unpacked and used. There are two ways to receive a message: by registering a receive callback, or by calling alp_ipc_connection_receive(). The callback method delivers the messages asynchronously via the GTK+ main loop. alp_ipc_connection_receive(), on the other hand, allow you to receive messages synchronously.

    When using alp_ipc_connection_receive(), you can indicate that you want to wait for a message with a specific message ID, or you can simply wait for any message to be received. If, while waiting for a message with a specific ID, messages with other IDs arrive, those messages are queued for delivery once alp_ipc_connection_receive() returns.

    Note that the message receiver—either the code calling alp_ipc_connection_receive() or the callback function that is called with the message—is responsible for deleting the AlpMessage by calling alp_ipc_message_destroy() after it is entirely done with the message.

  9. Unpack the received message.

    Before you can make use of the received message, you must first unpack it. The process of unpacking is very much like the packing process:

    • Call alp_ipc_message_unpack_start() to signal the beginning of the unpacking process.
    • Make zero or more calls to alp_ipc_message_unpack_type(), where type is the value type being extracted from the message (such as int32 or string). Note that the message receiver needs to know the format of the message, either ahead of time or based upon the initial contents of the message itself.
    • Call alp_ipc_message_unpack_end() to end the unpacking process.
  10. Destroy the message.

    Messages that have been sent over the connection and are no longer needed should be destroyed to avoid duplication and unnecessary memory consumption. Generally, the message receiver destroys the message by calling alp_ipc_message_destroy(), which cleans up and frees all memory associated with the message.

  11. The client disconnects from the channel.

    Once the client process no longer needs the channel, it should disconnect by calling alp_ipc_channel_disconnect(). Note that this function should only be called by a client process that successfully connected to the channel.

    The channel disconnect will trigger the disconnect callback in the server process (if one has been registered). It also destroys all memory and closes any file descriptors used internally by the connection.

  12. The server destroys the channel.

    The server process that originally created the channel destroys it with alp_ipc_channel_destroy(). This function should only be called by the process that originally created the channel. It notifies any clients that have registered a disconnect callback for that channel, then destroys all memory and closes any file descriptors used internally by the channel.

Advance Techniques

Set and Get Custom Data on a Channel

The Abstract IPC mechanism allows you to set and retrieve custom data on a channel or on a connection:

  • alp_ipc_channel_set_custom_data()
  • alp_ipc_channel_get_custom_data()
  • alp_ipc_connection_set_custom_data()
  • alp_ipc_connection_get_custom_data()
Get Peer IDs

alp_ipc_connection_get_peer_pid() returns the process ID of the peer process for a specified connection.

alp_ipc_connection_get_peer_uid() returns the user ID of the peer process for a specified connection.

alp_ipc_connection_get_peer_gid() returns the group ID of the peer process for a specified connection.


1. 3 seconds is a typical value for the Application Server's "kill timer." Note, however that this value can vary from device to device. In the Simulator, the timer value is 6 seconds.

 

Add as favourites (323) | Quote this article on your site | Views: 5755

Be first to comment this article
RSS comments

Only registered users can write comments.
Please login or register.

Powered by AkoComment Tweaked Special Edition v.1.4.6
AkoComment © Copyright 2004 by Arthur Konze - www.mamboportal.com
All right reserved

 


© 2009 ACCESS Developer Network    |    Joomla! is Free Software released under the GNU/GPL License.    |    ACCESS Global Website
Events Support Community Platforms Home