Reputation: 7243
I am trying to get a basic timer to work on Android and I have the following code in the onCreate() method:
editText = (EditText) findViewById(R.id.edit_message);
Timer time = new Timer();
time.schedule(new TimerTask() {
public void run() {
timesince++;
editText.setText("Timeran:"+timesince);
Log.d("TIMER", "TimerTask run");
}}, 0, 1000);
So hopefully it would update the textbox with a increasing value (timesince) -which is declared at top of program, along with editText...
However, (although I get no compile issues) when I run it on the emulator it does not work at all. App says 'blahblahblah has stopped working...'
Am I doing Timers wrong? What am I missing?
Thanks alot.
(P.S. App works fine if this code is removed so I know there is an issue with this section.)
EDIT: I believe this is my logcat output, sorry for wall of text:
10-11 03:40:49.260: E/AndroidRuntime(561): FATAL EXCEPTION: Timer-0
10-11 03:40:49.260: E/AndroidRuntime(561): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
10-11 03:40:49.260: E/AndroidRuntime(561): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:3939)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:714)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:763)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4012)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.view.View.invalidate(View.java:8454)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.TextView.invalidateCursor(TextView.java:4319)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.TextView.spanChange(TextView.java:7670)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.TextView$ChangeWatcher.onSpanAdded(TextView.java:8020)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.text.SpannableStringBuilder.sendSpanAdded(SpannableStringBuilder.java:898)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:614)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:520)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.text.Selection.setSelection(Selection.java:76)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.text.Selection.setSelection(Selection.java:87)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.text.method.ArrowKeyMovementMethod.initialize(ArrowKeyMovementMethod.java:302)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.TextView.setText(TextView.java:3244)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.TextView.setText(TextView.java:3110)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.EditText.setText(EditText.java:78)
10-11 03:40:49.260: E/AndroidRuntime(561): at android.widget.TextView.setText(TextView.java:3085)
10-11 03:40:49.260: E/AndroidRuntime(561): at com.example.cultivation.MainActivity$1.run(MainActivity.java:54)
10-11 03:40:49.260: E/AndroidRuntime(561): at java.util.Timer$TimerImpl.run(Timer.java:284)
Upvotes: 4
Views: 5769
Reputation: 5725
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
This is the problem
You have to move the portion of the background task that updates the ui onto the main thread or create the mHandler in your UI thread;
Update:
Updating the UI from a Timer : http://android-developers.blogspot.com/2007/11/stitch-in-time.html
Upvotes: 3
Reputation: 3412
or use handler to run update the textview:
private final Runnable mRunnable1 = new Runnable() {
public void run() {
timesince++;
editText.setText("Timeran:"+timesince);
Log.d("TIMER", "TimerTask run");
mHandler.postDelayed(mRunnable1, 1000);
}
};
and also call this line in OnCreate()
method mHandler.postDelayed(mRunnable1, 1000);
Upvotes: 2
Reputation: 3412
do the following:
declare Timer as global variable and call the timer function in a method like the following:
public void startThread(){
time.schedule(new TimerTask() {
public void run() {
timesince++;
editText.setText("Timeran:"+timesince);
Log.d("TIMER", "TimerTask run");
}}, 0, 1000);
}
and call this startThread()
function in onCreate()
Upvotes: 0
Reputation: 4942
Try to update the TextView
from a UI thread. Try to use a handler. Here you can find a good article on that. Update textview with the help of Handler
Upvotes: 0