I am trying to have a counter (count seconds and minutes) and update it on the display every second.
I have this code in the onCreate
of my class, which extends Activity
:
timeOnCall = (TextView) findViewById(R.id.time);
minutes = seconds = 0;
timeOnCall.setText(minutes + ":" + seconds);
// Implements the tim开发者_如何学运维er
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
++seconds;
if (seconds == 60) {
seconds = 0;
++minutes;
}
// Display the new time
timeOnCall.setText(minutes + ":" + seconds);
}
}, 1000, 1000);
Unfortunately, I get the following error:
android.view.ViewRoot$CalledFromWrongThreadException:
Only the original thread
that created a view hierarchy can touch its views.
I am not sure how to fix this as it's already in the onCreate()
method. Does anyone know a solution?
You can do it with a handler, something lite this:
final Handler mHandler = new Handler();
final Runnable updateText = new Runnable() {
public void run() {
timeOnCall.setText(minutes + ":" + seconds);
}
};
in onCreate you can then run:
onCreate(Bundle b) {
...
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
++seconds;
if (seconds == 60) {
seconds = 0;
++minutes;
}
// Display the new time
mHandler.post(updateText);
}
}, 1000, 1000);
}
Its because your trying to change the textview from inside a different thread. You can't do that. You need to post a message back to the thread that owns the textview.
public void run()
This starts a new thread that is separate from what is running your UI.
Edit: There are tons of examples online for the code you are looking for. Just Google something like "Android thread message handler."
Here is a complete step-by-step of what you are trying to do and doing it without a background thread. This is preferred over a timer because a timer uses a separate thread to do the update.
http://developer.android.com/resources/articles/timed-ui-updates.html
精彩评论