Many exceptions include Symbian OS error codes
in their description (Exception.toString
), which
can be useful in problem solving. For more information, see the list of Symbian OS error codes in the Nokia
Developer Wiki.
Any exception that is not handled by the application itself, will cause an error message “Unhandled exception” to be presented to the user. User can select if application should be closed or not.
Resources can be accessed using absolute or relative
paths - getResourceAsStream
method uses more
strict rules for accessing resources with relative paths than in previous
release (to be inline with MIDP 2.1 specification).
Relative
pathnames are relative to the class upon which getResourceAsStream
is called. Relative names are converted to absolute by prepending
a fully qualified package path.
For example, assuming MIDlet
has JAR directory structure illustrated below then getResourceAsStream(“bar.txt”)
succeeds but getResourceAsStream(“foo.txt”)
fails.
foo.txt
\hello\hello.class
\hello\bar.txt
\meta-inf\Manifest.mf
Previously it was possible to access foo.txt
using relative path as well.
Absolute path, getResourceAsStream(“/foo.txt”)
, should be used to access foo.txt
.
Threading does not act the same on different platforms unlike most of other Java aspects. Two main areas of difference are thread scheduling and thread priorities.
In Series 40, all Java threads run in an operating system task. The number of threads is effectively limited by Java heap memory. Java threads cannot run at higher priority than native code in Series 40.
In S60 3rd Edition FP 2 onwards, Java threading model has been changed to use native threading. This means that each Java thread maps to the native thread. Previously all Java threads ran in single native thread (green threads). Threading change is transparent for MIDlets and does not cause any issues for correctly implemented MIDlets.
For thread handling in MIDlets:
The choice of which thread the thread.notify
method wakes is arbitrary.
Java VM process can have maximum of 128 threads. The actual number of available threads is usually less as the VM implementation itself and stack size changes may reserve some threads.
Thread priorities should not be modified because this may not result in performance gains and may have adverse effects.
Thread.setPriority()
Symbian implementation uses native threading model where a Java thread maps to a native thread. Table below lists how Java thread priorities are mapped to native thread priorities.
Java thread priority |
Symbian OS thread priority |
---|---|
1...4 |
|
5...8 |
|
9...10 |
|
Thread priorities should not be modified. There are often better ways to solve timing or resource acquisition problems. Especially if high thread priorities are used then developer should understand the ramifications from whole Symbian OS point of view. Scheduler is not fair so a higher priority Java thread gets all the CPU it needs, which may starve lower priority Java threads.
Changing thread priority rarely gives any performance gains and it may have actually reversed effects.
In Series 40 the thread priority is not mapped to the native model.
Thread.yield()
Do not use
the thread.yield
method because it can lead to
busy loop-like behavior as yielding thread can be scheduled to run
immediately again if there are no other eligible threads to be run.
In Symbian, wait-notify
is always the better
alternative to a Thread.yield
loop, when a condition
needs to be acted on.
Thread.sleep()
Do not use
the thread.sleep
method because it can lead to
busy loop-like behaviour that can affect the battery life and other
applications.
Wait-notify should also be always preferred over Thread.sleep
looping, as Thread.sleep
does not react to events immediately (even a small sleep value takes
at least that long to react).
On Symbian devices, MIDlets can access native services through server applications created for that purpose. This allows MIDlets to use features that are not available in standard Java APIs.
MIDlets communicate with server applications using standard transport protocols (HTTP, sockets) over localhost (IP address 127.0.0.1).
The Java ME API Bridge is a service framework that provides a simple way for MIDlets to use native services. For instructions on how to use the Java ME API Bridge, see article J2ME API Bridge Interface in the Nokia Developer Wiki.
MIDlet suite runs in a VM process and there can be multiple MIDlet suites running at the same time. Java VM process is a normal process among other native applications, such as Browser or Calendar in Symbian OS.
Symbian OS scheduler handles execution between running threads. Scheduling is based on thread and process priority. Symbian OS scheduling is pre-emptive and round-robin method is used for same priority threads. Since Java uses native threading, the generated threads are scheduled by Symbian OS scheduler as well.
Process priority is typically assigned to be either background or foreground. Symbian OS changes process priority automatically depending whether application is on foreground or not. This applies also for Java VM process. The foreground and background MIDlets comply to the following guidelines:
The foreground application gets basically all the CPU time it requires.
The MIDlet is not paused automatically when it is assigned to the background. It can still consume CPU resources.
MIDlet developer can not affect to VM process priority itself
but Java thread priorities can be set via Thread.setPriority()
, see section Thread for more details.
If a MIDlet is the foreground application, its threads run on higher priority than most native applications. If the MIDlet is performing very resource consuming tasks, it may have a negative effect to native applications.
In Series 40, multitasking is supported by the operating system, but not the user interface. MIDlets are allowed to be hidden, effectively staying in the foreground. MIDlets are also allowed to go to proper background, but use of proprietary APIs is needed for that.
Multitasking example:
It is quite easy to make MIDlet that consumes a lot of CPU resources by accident. For example, let’s consider following code snippet:
void run() { while(true) { if( onForeground ) { doMyStuff(); } else { yield(); } } }
Intention was that if the MIDlet is not on foreground, the MIDlet should not do anything. Instead this MIDlet will have busy loop when it’s on background. This might have effects to other applications and even more importantly it will prevent device to go on power saving mode, which will have a drastic effect on battery life.
Better way to implement this would be using wait – notify mechanism instead of yield, see section Thread for more details.
TimeZone.useDaylightTime
always
returns false.
If your MIDlet does not handle an exception thrown
by timertask.run
method, then the Symbian platform
catches the exception silently.