views:

7461

answers:

2

For my Android application there is a timer that measures how much time has passed. Ever 100 milliseconds I update my TextView with some text like "Score: 10 Time: 100.10 seconds". But, I find the TextView only updates the first few times. The application is still very responsive, but the label will not update. I tried to call .invalidate(), but it still does not work. I don't know if there is some way to fix this, or a better widget to use.

Here is a example of my code:

float seconds;
java.util.Timer gametimer;
void updatecount() { TextView t = (TextView)findViewById(R.id.topscore);
t.setText("Score: 10 - Time: "+seconds+" seconds");
t.postInvalidate();
}
public void onCreate(Bundle sis) {
... Load the UI, etc...
  gametimer.schedule(new TimerTask() { public void run() {
     seconds+=0.1; updatecount();
} }, 100, 100);
}
+2  A: 

Hey Issac,

What I think is happening is you're falling off the UI thread. There is a single "looper" thread which handles all screen updates. If you attempt to call "invalidate()" and you're not on this thread nothing will happen.

Try using "postInvalidate()" on your view instead. It'll let you update a view when you're not in the current UI thread.

More info here

haseman
It still does not work - it updates the first time so I know its working but does not update after that. Thanks anyway, Isaac.
Isaac Waller
if you want to post a code snippit I'll take a look
haseman
I added some example code to my post - thanks!
Isaac Waller
The call to setText has to be on the UI thread as well.
Lance Nanek
+5  A: 

The general solution is to use android.os.Handler instead which runs in the UI thread. It only does one-shot callbacks, so you have to trigger it again every time your callback is called. But it is easy enough to use. A blog post on this topic was written a couple of years ago:

http://android-developers.blogspot.com/2007/11/stitch-in-time.html

Ben Bederson
Thank you for this link. The code on that page worked perfectly with my TextView-based timer.
borg17of20