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.

inside custom component

Java Development

Reply
Contributor
Posts: 49
Registered: ‎05-02-2012
My Device: Bold 9790
My Carrier: Wind Mobile
Accepted Solution

Timer that starts right away

Hi there everyone,

 

I've been having some trouble with Timer and TimerTask. I think that my TimerTask is okay but I'm not sure where to put my timer if I want it to begin when the app opens. Is it in the constructor for the screen? I keep getting IllegalStateException. All the examples I've looked at have timers that start when a button is pressed.

 

Timer t = new Timer() //This works fine

t.scheduleAtFixedRate(autoUpdate, 1, 60000); //autoUpdate is my TimerTask

 

I'm not sure whre to put this... but if I'm right it should start one millisecond after its created and run every minute?

 

Thank you,

Ben

Developer
Posts: 16,997
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport
My Carrier: O2 Germany

Re: Timer that starts right away

the constructor of the first screen is usually executed before (!) the application enters the event dispatcher, that can cause numerous issues.

to avoid this you could do the following:
- use onUiEngineAttached (basically, your screen is visible) to trigger (make sure it triggers only once)
- use invokelater, not to move it on the event thread, but to delay it's execution until the event dispatcher is ready.

your timertask should run after 1 ms and afterwards every minute, so that part looks correct.
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Timer that starts right away

"when the app opens" is a bit of a trick with BB apps.

 

Personally I would just stick the code you are having problems with in the constructor for UiApplication or Application, and enclose it in the following

UiApplciation.getUiApplication().invokeLater(new Runnable() {

public void run() {

// code in here

}

});

 

This will then run as soon as your Application has been dispatched as an Application rather than trying to do this while the app is being started up. 

Contributor
Posts: 49
Registered: ‎05-02-2012
My Device: Bold 9790
My Carrier: Wind Mobile

Re: Timer that starts right away

[ Edited ]

Thanks everyone for the advice,

 

Since I'm using the plugin for Eclipse I automatically get a myApp.java file and a myScreen.java file. If I understand correctly invokeLater would go in the constructor for myApp? I still have one probelm which is that if I put

 

Timer t = new Timer()

t.scheduleAtFixedRate(autoUpdate, 1, 60000);

 

there, autoUpdate is in myScreen so it can't see it, am I missing something?

 

Ben

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Timer that starts right away

You are missing something.

 

We are both talking about how to get your Timer process starting correctly.

 

We were not aware that you wanted to update a Screen in the processing.  To do this, you will have to run the Screen update code inside an invokeLater. 

 

There are referencing problems involved in achieving both of these.  But the easiest way of resolving them is to use Simon's suggestion of using  

onUiEngineAttached

in the screen you wish to update.  That should simplfy the processing too. 

 

Why do you need to update your screen every minute?

Contributor
Posts: 49
Registered: ‎05-02-2012
My Device: Bold 9790
My Carrier: Wind Mobile

Re: Timer that starts right away

[ Edited ]

Sorry about that,

 

Effectively my app is a school schedule. It shows the current time, the minutes left in the current class and what the next class is. I wanted to update these every minute, I will try the onUiEngineAttached method. Is there another way to do this?

 

Could I use onExposed()? Or would that end badly?

 

Thank you,

Ben

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Timer that starts right away

Just to confirm, the

onUiEngineAttached

is only to get the Timer started and stopped.  You will start on when attach is true, stop it when false.

 

After that you will update every minute as you want.  In your run() method, you will have to use invokeLater to update the screen.

 

Hope this makes sense.

 

You may want to optimize this processing, so that the update is not done when the application is in the background or another screen is displayed on top of your screen.  In either of these circumstances, you can stall the update until onExposed() is invoked.  But this is an efficiency thing rather than a method of achieving what you want. 

 

As an alternative, you could use the RealTimeClockListener.  Have a look at it.  The advantage of this is that the update will happen on the minute.  The disadvantage is it is more complicated. 

Contributor
Posts: 49
Registered: ‎05-02-2012
My Device: Bold 9790
My Carrier: Wind Mobile

Re: Timer that starts right away

[ Edited ]

So I would have

 

Timer t = new Timer();

 

TimerTask autoUpdate = new TimerTask() {

run() {

//Update Screen

//Or do I have to use invokeLater?

}

}

 

protected void onUiEngineAttached(boolean attached) {

if(attached) {

t.scheduleAtFixedRate(autoUpdate, 1, 60000);

}

else {

t.cancel();

}

}

 

Or something like that?

 

The app isn't very taxing so I don't think that efficiency will be a problem, I'll look at RealTimeClockListener.

 

Thanks so much,

Ben

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Timer that starts right away

That is pretty much it. 

 

You can worry about overhead and RealTimeClockListener later.  The priciples is what we are focusing on right now. 

Contributor
Posts: 49
Registered: ‎05-02-2012
My Device: Bold 9790
My Carrier: Wind Mobile

Re: Timer that starts right away

Awesome that part works I think, but when I try to put something in run() for the TimerTask it throws an IllegalStateException, do you know why? I tested it with something simple like

 

Date now = new Date();

rtf.setText(now.toString());

 

It lets me create the Date but it won't let me set the field to that date.Thank you, this is the first time I've tried to do something like this... Smiley Tongue

 

Ben