Blackberry Development 3: Single Threading and Event Testing

The BlackBerry UI API is single threaded. This means that all UI updates and events are handled by the same thread—or more precisely, they must be handled while holding the event lock, which most of the time is held by the UI thread.

First, let’s change labelFieldto be a member variable instead of a variable local to the constructor, and add a method to append text to it:

public class HelloWorldMainScreen extends MainScreen {

    private LabelField labelField;

    public HelloWorldMainScreen() {
        labelField = new LabelField("Hello World");
        add(labelField);
    }

    public void appendLabelText(String text) {
        labelField.setText(labelField.getText() + "\n" + text);
    }

}

Because appendLabelText calls LabelField.setText, the call can only be made from the event thread. If you attempt to call this method directly from another thread, an exception will be thrown.

Now, we’ll define the thread class that will actually do the testing. It will loop from 1 to 10. In each iteration, it will wait 5 seconds and then add some text to the LabelField. Create a new class called MainScreenUpdaterThread that extends java.lang.Thread. The full source code follows:

package com.henry416;

import net.rim.device.api.ui.UiApplication;

public class MainScreenUpdaterThread extends Thread {
    HelloWorldMainScreen mainScreen;

    public MainScreenUpdaterThread(HelloWorldMainScreen mainScreen) {
        this.mainScreen = mainScreen;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {

            try {
                 Thread.sleep(5000);
            } catch (InterruptedException ex) {

            }
            // Queue a new task on the event thread
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                 public void run() {
                    mainScreen.appendLabelText("Testing");
                 }

            });

        }
     }
}

To actually update the UI, we’re using an anonymous inner class, which is a class that we define at the point where we instantiate it. Our anonymous inner class calls the one method that needs to be called on the event thread: appendLabelText (which calls LabelField.setText).

We’ll start our thread in the HelloWorldMainScreen constructor as follows:

    public HelloWorldMainScreen() {
        labelField = new LabelField("Hello World");

        add(labelField);

        MainScreenUpdaterThread thread = new MainScreenUpdaterThread(this);
        thread.start();
    }

Finally, running this application will produce the following results:

HelloWorld
Testing
Testing
Testing
Testing
Testing

Try to modify the above method with the following method:

    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException ex) {

            }
            // Ensure we have the event lock
            synchronized(UiApplication.getEventLock()) {
                mainScreen.appendLabelText("Testing Again");
            }
        }
    }

About henry416
I am a computer technology explorer and an university student based on Toronto. If you have any question, please feel free to discuss and comment here

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s