1

I'm running the following code in my main class, just to have a counter that counts down the days, hours, minutes and seconds until Christmas. From what I can see, I think my code is correct (although, as it's throwing an Exception, it's probably not). Can anyone see what the error is?

final TextView mTextField = new TextView(this);

    Calendar xmas = Calendar.getInstance();
    Calendar now = Calendar.getInstance();

    xmas.set(2011, 12, 25);

    long milliseconds1 = now.getTimeInMillis();
    long milliseconds2 = xmas.getTimeInMillis();
    long diff = milliseconds2 - milliseconds1;
    final long diffSeconds = diff / 1000;
    final long diffMinutes = diff / (60 * 1000);
    final long diffHours = diff / (60 * 60 * 1000);
    final long diffDays = diff / (24 * 60 * 60 * 1000);

    int delay = 1000; // delay for 1 sec.
    int period = 1000; // repeat every sec.

    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask()
        {
            public void run()
            {
                mTextField.setText("Days : " + diffDays + " Hours : "  + diffHours + " Minutes : " + diffMinutes + " Seconds : " +diffSeconds);
            }
        }, delay, period);
     setContentView(mTextField);

The stack trace is as follows...

   10-29 17:27:19.258: ERROR/AndroidRuntime(471): FATAL EXCEPTION: Timer-0
10-29 17:27:19.258: ERROR/AndroidRuntime(471): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.view.ViewRoot.requestLayout(ViewRoot.java:629)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.view.View.requestLayout(View.java:8267)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.view.View.requestLayout(View.java:8267)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.view.View.requestLayout(View.java:8267)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.view.View.requestLayout(View.java:8267)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.widget.TextView.checkForRelayout(TextView.java:5514)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.widget.TextView.setText(TextView.java:2724)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.widget.TextView.setText(TextView.java:2592)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at android.widget.TextView.setText(TextView.java:2567)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at com.android.sleeps.SleepstosantaActivity$1.run(SleepstosantaActivity.java:44)
10-29 17:27:19.258: ERROR/AndroidRuntime(471):     at java.util.Timer$TimerImpl.run(Timer.java:284)

Line 44 is mTextField.setText("Days : " + diffDays + " Hours : " + diffHours + " Minutes : " + diffMinutes + " Seconds : " +diffSeconds);

David
  • 19,577
  • 28
  • 108
  • 128
  • 3
    can you provide the exception information from logcat? – Will Tate Oct 29 '11 at 16:22
  • 3
    Whenever you ask a question with an exception, you should say what the exception is. Don't leave us guessing. – Jon Skeet Oct 29 '11 at 16:23
  • Ah, my apologies, the emulator only responds with "The application myapp (process com.android.myapp) has stopped unexpectedly. Please try again. Is there anywere the android emulator logs exception (or stack trace?) – David Oct 29 '11 at 16:25
  • 1
    Yea, checkout the logcat: http://developer.android.com/guide/developing/tools/logcat.html When ever you're asking a question about an exception in Android, we're generally going to want to know what's going on in the logcat. – Kurtis Nusbaum Oct 29 '11 at 16:28

2 Answers2

2

Try using a handler instead of a timer, from the log it looks like the problem is that you can't make changes to the UI from your timerTask.

http://developer.android.com/reference/android/os/Handler.html

There's some good examples here:

How to run a Runnable thread in Android?

Use postDelayed to provide a delay between operations.

Your logic is flawed, it should look something more like this:

diff = diff /1000;
final long diffSeconds = diff % 60;
diff = diff / 60;
final long diffMinutes = diff % 60;
...

I haven't tested this but should work.

Community
  • 1
  • 1
Alan Moore
  • 6,525
  • 6
  • 55
  • 68
  • Thanks, I changed it to use the runnable thread as you said, but I get Days : 88 Hours : 2113 Minutes : 126780 Seconds : 7606800, can you see anything wrong with my logic? – David Oct 29 '11 at 16:43
  • Yes, your logic needs some work for sure! First you need to use the modulus operator. Then you need to subtract each piece as you go. I'll put a little code in for you... – Alan Moore Oct 29 '11 at 17:12
0

You cannot interact with the views from a Thread. Timer is basically a Thread. You will have to use a handler here with the timer.

Kumar Bibek
  • 9,016
  • 2
  • 39
  • 68