Welcome!

Welcome to the Official BlackBerry Support Community Forums. This is your resource to discuss support topics with your peers, and learn from each other. New to the forum? Please visit the ‘Getting Started’ link below.
inside custom component

Java Development

Sample "Please Wait" screen - part 1

by Developer on ‎07-02-2010 02:57 PM - edited on ‎09-20-2010 04:51 PM by Administrator

 

Many BlackBerry® smartphone applications need to wait for some network activity (or another blocking operation, which must process in the background), while still holding up the User Interface (UI) and displaying a progress indicator.

 

There seem to be two common issues when programming this:

  1. As applications are not allowed to block the Event Thread, how do they get the UI processing to wait?
  2. How can the background Thread update the UI?

 

This article is intended to help with these issues and provide a fully functioning "Please Wait" sample Popup Screen. However, as there is quite a lot to explain, in this first article, we will just create a popup screen that will show itself, hold up the UI, and then remove itself once the background processing has finished. This does not give us any progress indication, nor does it let the user cancel the wait. These points will be covered in a followup article. But the code supplied with this article will be useful anyway, especially when the duration of the background processing is not known and the user may not cancel the processing. 

 

First, we start with the background processing we need to run. While this could be anything, typically this will be network processing, like the following:

 

httpConn = (HttpConnection)Connector.open(_url + ";deviceside=true");
responseCode = httpConn.getResponseCode();
responseMessage = "Response Code: " + Integer.toString(responseCode);

 

To initiate this network processing, we have a MainScreen that contains

  1. A BasicEditField that allows the entry of a URL
  2. A RichTextField that should display the response code (or error message). Here are the important parts of that screen:

 

BasicEditField _requestedURLField = new BasicEditField("http://", "www.blackberry.com", 255, BasicEditField.FILTER_URL);
RichTextField _responseField = new RichTextField("<response code>", RichTextField.NON_FOCUSABLE); 

 

We would like the MainScreen to be updated with the result.  As noted above, background processing can't directly update the UI; UI updating code must be on the Event Thread. There are several ways to get a background process onto the Event Thread, see the related article for more. In this case, we will use the following code:

 

// Make things final so we can use them in the inner class
final String textString = responseMessage;
final RichTextField rtf = _resultField;
UiApplication.getUiApplication().invokeLater(new Runnable() {
    public void run() { 
rtf.setText(textString);
    }
});

Now we must define the PleaseWaitPopupScreen to be displayed while waiting. 

 

To give the user something to look at while they are waiting, we have an animated .gif, which is diplayed using the code in the AnimatedGIFField (see related link). And, so the user knows what they are waiting for, the PleaseWaitPopupScreen is supplied with a String to display, as the following constructor shows:

 

private PleaseWaitPopupScreen(String text) {
    super(new VerticalFieldManager(VerticalFieldManager.VERTICAL_SCROLL | VerticalFieldManager.VERTICAL_SCROLLBAR));
    GIFEncodedImage ourAnimation = (GIFEncodedImage) GIFEncodedImage.getEncodedImageResource("cycle.agif");
    _ourAnimation = new AnimatedGIFField(ourAnimation, Field.FIELD_HCENTER);
    this.add(_ourAnimation);
    _ourLabelField = new LabelField(text, Field.FIELD_HCENTER);
    this.add(_ourLabelField);
}

 

PleaseWaitPopupScreen provides a method – showScreenAndWait(..) – which will create and display the Popup screen, run the Background processing, and then dismiss the Popup screen. 

 

The final piece of the puzzle involves supplying showScreenAndWait(..) with the processing to run.

 

Java has the concept of a Runnable, which is an Object that contains a public void run() method that should be executed. In this case, we have the Connection code and screen update code, given above, that should be executed. So, this code is packaged up into a new Runnable Object, which is supplied to showScreenAndWait(..). And here is that method. Note how a new Thread is created and run. 

 

public static void showScreenAndWait(final Runnable runThis, String text) {
    final PleaseWaitPopupScreen thisScreen = new PleaseWaitPopupScreen(text);
    Thread threadToRun = new Thread() {
        public void run() {
            // First, display this screen
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    UiApplication.getUiApplication().pushScreen(thisScreen);
                }
            });
            // Now run the code that must be executed in the Background
            try {
                runThis.run();
            } catch (Throwable t) {
                t.printStackTrace();
                throw new RuntimeException("Exception detected while waiting: " + t.toString());
            }
            // Now dismiss this screen
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    UiApplication.getUiApplication().popScreen(thisScreen);
                }
            });
        }
    };
    threadToRun.start();
}

 

And this is the key part of the PleaseWaitPopupScreen. Note how this code will create and display a Popup screen to the user, including an animated icon, while it is running the background processing. Input from the user is blocked by the Popup screen until the processing completes. The originating screen is updated as a result of the background processing.

 

Download the associated .zip archive, which contains the source included in this article.

 

In the next article, we will extend this code to be able to handle:

a) Status updates from the Background Thread

b) "Time to go" indication

c) Being cancelled by the BlackBerry smartphone user

 

Additonal Links

Sample "Please Wait" screen - part 2

Sample "Please Wait" Screen - part 3

Comments
by Administrator on ‎06-11-2010 09:51 AM

Ready for publication.

by Developer on ‎09-08-2010 05:51 AM

This code is based on the idea of using the Observer Interface.

 

However some people just want to Block until the invoked Thread is completed.  There is a relatively simple change that you can make to this code that will facilitate this.  It is documented here:

http://supportforums.blackberry.com/t5/Java-Development/PleaseWaitPopupScreen/m-p/544983#M110325

 

At some stage I hope to update this article of create a new one based around a locking approach rather than the Observer approach, because I think that people find the blocking approach much easier to implement.

 

Cheers: Peter Strange

by Developer on ‎09-18-2010 05:09 PM

Do I have "edit" option to this article?

 

No! Seems I don't :smileysad: But Someone who has a edit option, please add part two's link to this article.

 

http://supportforums.blackberry.com/t5/Java-Development/Sample-quot-Please-Wait-quot-screen-part-2/t...

 

I think It makes more sense when the link is part of this article, rather than just a comment.

 

Cheers,

by Administrator on ‎09-20-2010 04:38 PM

No, you won't be able to edit articles (only create them).

 

Good point though.  I'll add links to the other parts.