Because Symbian OS is such a
powerful host, it has some capabilities that are not common on the
majority of feature-phone Java ME platforms. Symbian OS is a powerful
native platform and Java ME exposes that power through standard Java ME
APIs. The platform has to support both the more advanced JSRs and their
optional features. Symbian OS v9 and later versions support many JSRs.
When looking for an advanced and powerful JSR (for example, JSR-184 3D
graphics or JSR-226 SVG), you can assume that it is supported.
For example, javax.microedition.io.SocketConnection is optional in MIDP 2.0 but has been supported in Symbian OS for a long time, even in older smartphones. javax.microedition.io.ServerSocketConnection is still optional in MSA 1.1 but is supported on all Symbian smartphones.
The MIDP 2.0 specification does not define which
protocols and services must be supported by the Push Registry, yet the
support of Java ME on Symbian OS protocols exceeds the MSA 1.1 mandated
list; for example, the Push Registry supports TCP server sockets.
For a developer, a powerful common Java ME implementation for many devices improves the predictability of advanced features.
We do not list all of the optional features for all
Symbian smartphones because such a list would be long, quite tedious and
of questionable value. We are not attempting to provide you with
answers for every possible question; we're trying to provide you with
the right questions and the right techniques or advice to answer the
questions.
1. Multitasking Between Applications
One of the powerful features of Symbian OS is that
there can be more than one application running at the same time and the
user (or Symbian OS itself) may switch between applications and move
them between the foreground and the background. For example, the user
can start a Java application, switch to the applications menu and start
another native application and possibly a third Java or native
application as well. Since Symbian OS is a multitasking operating
system, all three applications can continue running concurrently without
being terminated. The AMS can also move an application to the
background, for example, when the device receives a phone call. This is a
major difference from low-end platforms, in which switching from the
current application to another terminates the former application.
Your Java application needs to be designed with
moving between the background and foreground in mind. It must be 'a good
citizen'; while it is in the background, it must allow the foreground
application to acquire the resources it needs. To ensure this, adhere to
the MIDlet lifecycle guidelines:
When your application is sent to the background, the MIDlet.pauseApp()
method is called and the MIDlet should release temporary resources and
become passive (e.g., it should close open connections and pause
rendering application threads).
When your application is brought back to the foreground, the MIDlet.startApp()
method is called and the MIDlet can acquire any resources it needs and
resume (e.g., it should resume application threads that handle the UI
rendering).
The following snippet of code illustrates an implementation of MIDlet.startApp() and MIDlet.pauseApp():
public void startApp() {
if (!started) {
// MIDlet started first time
workerThread = new WorkerThread();
started = true;
}
// MIDlet brought to foreground
paused = false;
workerThread.resumeWork();
}
public void pauseApp() {
// MIDlet sent to background
paused = true;
workerThread.pauseWork();
}
Your application should not consume resources, such
as CPU, for operations that are not necessary while in the background
(e.g., rendering threads) but it is still alive and running. Depending
on the core task of your application, it may be possible to fulfill some
of those tasks even when running in the background. For example, if
your application is registered to receive events, such as incoming SMS
messages or location notifications, the registration for receiving
events does not need to be removed every time the MIDlet is sent to the
background.
To illustrate such a case, the following example implements WMA MessageListener,
which queues or displays an incoming message according to the state of
the application. If the application is in the Paused state, then only
minimal processing is done. If the application is Active, then it should
operate with full functionality enabled.
public void notifyIncomingMessage(MessageConnection conn) {
if (paused) {
// TODO: silently add incoming message to queue, to be handled later
} else {
// TODO: display incoming message to user or perform another action
}
}
2. Multitasking of MIDlets in the Same Suite
Let's see how two MIDlets from the same suite, both
running at the same time, can not only access the same classes in the
JAR file but also invoke methods of objects owned by the other running
MIDlet. All MIDlets from the same suite run in the same space. A new
Java ME run-time process is spawned for every suite and all MIDlets from
that suite run within that process and in the same Java memory space;
this implies that MIDlets from the same suite can communicate,
programmatically.
For example, MIDlet1 and MIDlet2 are both in the same suite:
public class MIDlet2 extends MIDlet implements CommandListener {
public static int value = 0;
public static MIDlet2 instance;
public Object lock = new Object();
private Form form = new Form("MIDlet2");
private Command okCmd = new Command("Show Value", Command.OK, 0);
public MIDlet2() {
form.addCommand(new Command("Exit", Command.EXIT, 0));
form.addCommand(okCmd);
form.setCommandListener(this);
instance = this;
}
public void commandAction(Command cmd, Displayable arg1) {
if (cmd.getCommandType() == Command.EXIT) {
notifyDestroyed();
}
if (cmd == okCmd) {
form.append("\nvalue=" + value);
}
}
As you can see, when you press the Show value button, MIDlet2 prints the integer member value. So far, not very exciting.
Because MIDlet1 and MIDlet2 run in the same memory space, MIDlet1 can change MIDlet2.value from its CommandListener.command-Action() implementation:
public void commandAction(Command cmd, Displayable disp) {
if (cmd.getCommandType() == Command.EXIT) {
notifyDestroyed();
}
if (cmd == incCmd) {
// change MIDlet2.value member, from MIDlet1
MIDlet2.value++;
}
}
This is quite exciting but we can do something even
more entertaining and invoke methods in MIDlet2 from MIDlet1. For
example, let's add to MIDlet2 that, when a command is pressed, it waits
on a thread and a method that resumes the waiting thread:
public void wakeUp() {
try {
synchronized (lock) {
lock.notify();
}
}
catch (Exception e) {
form.append("err: " + e);
}
}
private void waitForNotify() {
new Thread() {
public void run() {
try {
form.append("\nzzz...");
synchronized (lock) {
lock.wait();
}
form.append("\noy!");
}
catch (Exception e) {
form.append("err: " + e);
}
}
}.start();
}
MIDlet2 invokes waitForNotify() when we press a new button:
if (cmd == waitCmd) {
this.waitForNotify();
}
And now comes the fun part – we let MIDlet1 invoke MIDlet2.
if (cmd == notifyCmd) {
MIDlet2.instance.wakeUp();
}
Let's run the example. We start both MIDlet1 and
MIDlet2. In MIDlet2, we press Wait and now there is a thread in MIDlet2
which is waiting. We switch back to MIDlet1 and press Wake up. When we
move back to MIDlet2, we see the screen in Figure 1. During all that time, there can be other applications, Java or native, running in the background (see Figure 2).
Multiple applications can run concurrently and
multiple applications from the same suite even run in the same space.
There is power here that you can use but which should be handled with
care.
3. MIDP Applications and Symbian Signed
One of your friends or colleagues may ask you, "Have
you passed your application through Symbian Signed?" The question might
confuse you (or, possibly, cause a massive panic if you are about to
release an application to a very demanding customer).
Symbian Signed is a program run by Symbian for and on
behalf of the wireless community to digitally sign applications which
meet certain industry agreed criteria. If a native application is
Symbian Signed, it has successfully met the criteria defined in the
Symbian Signed Test Criteria.
However, the Symbian Signed program is not relevant
for MIDP applications. MIDP defines its own security policy that applies
and usage of restricted APIs and functions requires permissions granted
either by signing the suite or explicitly by the user. MIDP
applications are considered safe and secure from the platform
perspective and there is no reason to impose an additional security
mechanism on MIDP applications. MIDP applications are, therefore, exempt
from passing Symbian Signed.