1
votes

I'm fairly new to writing BlackBerry applications, so maybe this is a stupid thing I'm overlooking. I have to use JDE 5 (client requirement) to support the older BlackBerry Curve 8520 phones.

What I am experiencing is that as soon as I place a DateField on my interface, the application slows down considerably, causing the UI to stutter. Even a simple layout that only has a single DateField and a button has the same effect. Then, as soon as I move on to the next layout, everything is fine again.

One of the layouts are created as follows (please comment if this is the incorrect way of doing it):

public void displaySomeLayout() {
    final ButtonField okButton = new ButtonField("OK");
    final DateField dobField = new DateField("Birthday", System.currentTimeMillis(), DateField.DATE);

    /* some other non-ui code */

    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
            applicationFieldManager.addAll(new Field[] {
                    dobField,
                    okButton
            });
        }
    });
}

The application then just slows down a lot. Sometimes, after a minute of so it starts responding normally again, sometimes not.

The displaySomeLayout() method is called from the contructor of the Screen extending class. And then applicationFieldManager is a private VerticalFieldManager which is instantiated during class construction.

1
Where are you putting the code you show above? Is it in the constructor for a Screen subclass, maybe? And what does methodToGetObjectArray() return? Does it return many, many objects, or just a few? - Nate
@Nate - It is not in the constructor. It is run when a specific method is called on that Screen (to update it's display). The methodToGetObjectArray() returns about 250 elements, but I have found that the phone handles it just fine. It's as soon as the DateField gets added that things go slow. - Nico Huysamen
That's different from what you said in your question. In the question, it says that adding the ObjectChoiceField or the DateField causes the problem. If the ObjectChoiceField is not the problem, please don't show us that code. Show us the code that is the problem, as you see it. Also, you still didn't really answer the question regarding where the code you show is run. Finally, 250 choices is actually a lot. That sounds like a UI that users will hate to scroll through. Is 250 really necessary? - Nate
@Nate Yes it is necessary unfortunately, they need to choose their country of residence. I will update my question wrt your other questions. - Nico Huysamen
Thanks for the clarifications, Nico. - Nate

1 Answers

0
votes

I'm not sure the problem is in the code that you've shown us. I think it's somewhere else.

However, here are a couple recommendations to improve the code you've shown:

Threading

First of all, the code you show essentially is being run in the Screen subclass constructor. There is almost no difference between this code:

public MyScreen() {
   Field f = new ButtonField("Hello", ButtonField.CONSUME_CLICK);
   add(f);
}

and this:

public MyScreen() {
   addField();
}

private void addField() {
   Field f = new ButtonField("Hello", ButtonField.CONSUME_CLICK);
   add(f);
}

So, because your code is being run in the screen class's constructor, it should already be running on the UI thread. Therefore, there's no reason to use UiApplication.getUiApplication().invokeLater() here. Instead, just use this:

public void displaySomeLayout() {
    final ButtonField okButton = new ButtonField("OK");
    final DateField dobField = new DateField("Birthday", System.currentTimeMillis(), DateField.DATE);

    /* some other non-ui code */

    applicationFieldManager.add(dobField);
    applicationFieldManager.add(okButton);
}

Sometimes, you do need to use invokeLater() to run UI code, even when you're already on the UI thread. For example, if your code is inside the Manager#sublayout() method, which runs on the UI thread, adding new fields directly will trigger sublayout() to be called recursively, until you get a stack overflow. Using invokeLater() can help there, by deferring the running of a block of code until sublayout() has completed. But, from the constructor of your screen class, you don't need to do that.

ObjectChoiceField

I'm also worried about the ObjectChoiceField you said you were using with 250 choices. You might try testing this field with only 10 or 20 choices, and see if that makes a difference.

But, even if the 250 choice ObjectChoiceField isn't the cause of your performance problems, I would still suggest a different UI.

On BlackBerry Java, you can use the AutoCompleteField. This field can be given all the country choices that you are now using. The user starts typing the first couple letters of a country, and quickly, the list narrows to just those which match. I personally think this is a better way to get through a very large list of choices.