|
Push starts a MIDlet in response to receiving an inbound connection for that MIDlet. For a MIDlet to use this functionality, it must add an entry in the Push Registry for the port that it will use and, optionally, the entities from which it will accept a request. (If a MIDlet will use more than one port, it must put multiple entries into the Push Registry.) There are two ways that a MIDlet can add the entry for its inbound connections. One is with an attribute-value pair in the application descriptor file; the other is by adding the entry at runtime.
The push implementation has a native layer and a Java™ programming language layer (Java layer). This chapter discusses how to port and customize the push implementation. Because you could implement push in a number of ways, the chapter begins by covering some design decisions that will affect your port.
The push functionality depends on persistent storage, AMS, security, and networking. The porting of these components was described in earlier chapters.
This chapter has the sections:
There are many ways that a device could provide the push functionality. Issues that will affect your design include the protocols that you will accept, how MIDP will listen for messages, buffering, whether the device supports running multiple MIDlets concurrently, and how to handle user interaction. This section covers those decisions.
From the protocols that you have supported in your networking port, you can choose which will be available for push functionality. You can have a protocol that accepts messages in your MIDP implementation (for example, a MIDlet might use server sockets if they are supported on your device) but you do not have to use that protocol as a reason to launch a MIDlet. You can also support additional protocols, such as the Bluetooth protocols specified in “Java™ APIs for Bluetooth” (JSR 000082), the short message service (SMS) and cell broadcast service (CBS) specified in “Wireless Messaging API” (JSR 000120), and so on. (For more information on these Java specification requests, see http://jcp.org
The MIDP Reference Implementation supports datagram and server socket connections for push functionality.
MIDP must listen for inbound connection notifications, so that it can launch a MIDlet to handle the incoming message. It can listen using native callbacks or a polling mechanism. Using native callbacks to implement asynchronous I/O is a better technical solution if the device has multithreading or interrupt callback capability. Comparatively, polling uses more resources because it periodically checks for new input, and it is not as timely if the polling cycle is too large.
The MIDP Reference Implementation uses polling.
The requirements for message buffering are protocol-specific. A MIDP implementation must support buffering for some protocols, but it is not required for all protocols. What is required, however, is that if your MIDP implementation buffers messages, it must provide them to the MIDlet when the MIDlet is launched and opens the push connection.
When your MIDP implementation supports datagram connections for push, it must buffer at least the first message. MIDP must be able to give the launched MIDlet at least the datagram that caused it to start when the MIDlet opens the UDPDatagramConnection.
When your MIDP implementation supports socket connections for push, it does not have to buffer any messages. MIDP must only ensure that the launched MIDlet can open the ServerSocketConnection and accept the connection, if the connection hasn't timed out.
If your device has limited space resources, you might decide to limit message buffering for some protocols. For example, if you support SMS messaging, you might be able to cache only a certain number of messages.
The MIDP Reference Implementation buffers the first message and the inbound connection sent to a MIDlet using the datagram protocol. It also accepts the inbound connection for a server socket. MIDP uses the data from these operations to check whether the MIDlet registered to receive data from the message’s source. It does this check before disturbing any running application.
When a message arrives for a MIDlet, the push functionality cannot launch the MIDlet without the user’s acknowledgement. Users need to be in control so that applications don't randomly disrupt what they are doing. You must decide how to present the request to interrupt the currently running MIDlet for the push. That is, will your users have to allow the interruption each time, or will you give them the ability to allow the MIDlet to be launched on future occasions? Requiring users to agree to launching the MIDlet each time burdens them with more frequent interruptions to which they must respond. On the other hand, if you give them the ability to agree to future launching, you must develop and support a way to let them change their mind at a later date.
The MIDP Reference Implementation gives users the ability to allow future launches of the MIDlet. It also has a preference that users can set so that they can again be asked each time before they are interrupted (or to allow future launches if they had chosen to be asked each time).
Some devices can run multiple MIDlets concurrently, while others can run only one MIDlet at a time. Which type of device you have might effect the behavior of your push functionality.
When MIDP starts a MIDlet because of a push message, it must do something with whatever MIDlet is currently running. If your device can run only one MIDlet at a time, MIDP will have to exit the currently running MIDlet so that it can launch the MIDlet receiving a message. If your device can run multiple MIDlets concurrently, you can choose whether MIDP will pause or exit the currently running MIDlet.
Choosing to pause the currently running MIDlet may be easier on the user: when the MIDlet is resumed, the user might be able to pick up from the point where the MIDlet was paused. In addition, pausing a well-behaved MIDlet should give the launched MIDlet access to the full resources of the device because a paused MIDlet should have released its shared resources (such as its network connections, cached images, open record stores, and so on). If you choose to exit the currently running MIDlet, the user will have to start over with it after the launched MIDlet exits.
Exiting the MIDlet, though, has the advantage of forcing the MIDlet to release its resources. Your users will not have failures due to resource shortages caused by a MIDlet that did not release its resources when it was paused.
The MIDP Reference Implementation exits a currently running MIDlet before launching the MIDlet receiving a message.
The push mechanism listens for inbound connections on all ports entered into the push registry, and must continue to listen even across restarts of the virtual machine (VM). To listen continuously, the low level implementation must interact with the device to intercept requests to open and close network connections. It must also be able to access and manage the push registry.
To enable this persistence, the native code called JAM (Java application manager) in CLDC that is run prior to launching the VM must open and read the push registry, and open all the inbound connections. This happens in the general start up of the system, as the following pseudo-code for main.c shows. The file descriptors can then remain open even when the VM is stopped and restarted.
Native code checks the open connections for new messages and manages the push registry. The native code is in the src/share/native/pushregistry.c file. (When the VM is running, the class PushRegistryImpl uses the functions in the pushregistry.c file to check for new connections, and when it adds, deletes, and lists entries in the Push Registry.)
In addition to its own native code the push implementation uses native code for socket and datagram. When the push implementation opens a connection to receive an inbound message, the native code for the message’s protocol checks out an open file descriptor. The push mechanism passes the open file descriptor to the MIDlet when it launches the MIDlet. When the MIDlet exits, the native code for the message’s protocol checks in the open file descriptor. (For more information on the native code for the network protocols, see Chapter 8, “Networking.”)
The MIDP Reference Implementation can easily pass a file descriptor to a MIDlet because CLDC, the push functionality, and the launched MIDlet are in a single process. If your device uses separate processes for the MIDlets and the push functionality the file descriptors may not be as easy to share. You may need to use some form of interprocess communication to achieve the check-in/check-out behavior.
The MIDP Reference Implementation implements the push registry in the Java programming language. It uses the following interface and class:
javax.microedition.io.PushRegistrycom.sun.midp.io.j2me.push.PushRegistryImpl
The PushRegistryImpl class handles:
The number of changes that you need to make to the PushRegistryImpl class to customize the push functionality depends on the decisions you made on the issues in section Section 10.1 “Design Considerations. If your platform is very different (for example, it supports concurrently running MIDlets and you have decided not to exit the currently running MIDlet), you will have to replace some or all of the code.
If you do make major changes to the MIDP Reference Implementation’s push code, make sure that your implementation has at most once semantics for launching a MIDlet to receive a message. Never notify the application twice for the same message.
|
Porting MIDP MIDP Reference Implementation, Version 2.0 FCS |
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.