Thursday, May 24, 2007

Responsive UI: do the heavy lifting in backgroup thread

Slow wireless connection, less processing power, less memory, all these factors make JavaME applications tend to feel sluggish. One trick we developers can play is to use background thread to do the heavy lifting parts.

The sample code below shows how one can use a separate thread to perform the time consuming task, while the UI still interacts with user, and update the UI when the task is completed.

Please note that the Runnable object passed to UiApplication.invokeLater() should return quickly. The Runnable object is put into the event queue to be executed by the event dispatcher thread. During the time this runnable is executing, all new UI events are queued so the UI will not respond to any input.


package com.mycompany.sample;

import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.AutoTextEditField;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.container.MainScreen;

public final class DemoBackgroundThread extends UiApplication {
public DemoBackgroundThread(){
super();
pushScreen(new EditorScreen());
}

public static void main(String[] args) {
new DemoBackgroundThread().enterEventDispatcher();
}

private static class EditorScreen extends MainScreen {
private AutoTextEditField _firstNameField;
private AutoTextEditField _lastNameField;
private ObjectChoiceField _timezoneField;
public EditorScreen()
{
super();
_firstNameField = new AutoTextEditField("First Name: ", "");
_lastNameField = new AutoTextEditField("Last Name: ", "");
_timezoneField = new ObjectChoiceField("Timezone: ", new String[]{"Loading Timezones"});
add(_firstNameField);
add(_lastNameField);
add(_timezoneField);
new Thread(new Runnable() {
public void run() {
final String[] zones = new String[6];
zones[0] = "-Select Timezone-";
for(int i = 1; i < zones.length; i++) {
try {
//do the heavy lifting here, like fetching data from remote server or heavy calculations.
Thread.sleep(1000);
} catch (InterruptedException e) {
//who cares
}
zones[i] = "GMT-"+i;
}
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run() {
_timezoneField.setChoices(zones);
}
});
}
}).start();
}
}
}

No comments: