James Andrew
James Andrew

Reputation: 7243

Android Simple Timer/Timertask issue

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

Answers (4)

Nam Vu
Nam Vu

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

G M Ramesh
G M Ramesh

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

G M Ramesh
G M Ramesh

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

BBdev
BBdev

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

Related Questions