2

I have a very simply activity that prints a custom date time string to a textView. I implemented a runnable interface in the MainActivity it self and created a Thread at the end of onCreate method.

Thread thread = new Thread(this);
thread.run();

This is the run method

public void run() {

        while (true) {
            try {
                Thread.sleep(1000);
                localTime.setText(LocalTime.getTime().format2445());
                System.out.println(LocalTime.getTime().format2445());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    } 

When i run it on the emulator i can see the System out in logcat. But the emulator shows ANR after about 5 seconds. What am i doing wrong. Is this method not suitable? is Async Task is the way to go here? I need to update the clock every second so is having a AsyncTask run forever is an acceptable pattern?

DevZer0
  • 13,433
  • 7
  • 27
  • 51

5 Answers5

3

I need to update the clock every second so is having a AsyncTask run forever is an acceptable pattern?

No, this is not recommended. According to AsyncTask Documentation, these should only run for short periods of time. I would recommend you use a Timer and TimerTask for this.

Timer timer;

public void onStart() {

    timer = new Timer();

    //this will update each second
    timer.scheduleAtFixedRate(new UpdateTask(), 0,1000);
}

class UpdateTask extends TimerTask {
    public void run() {
        //update TextView
    }
}

public void onStop(){

    timer.cancel();
}
Joel
  • 4,732
  • 9
  • 39
  • 54
2

Try something like this.

new Thread(new Runnable() {
public void run() {
  Thread.sleep(1000);
  localTime.setText(LocalTime.getTime().format2445());
  System.out.println(LocalTime.getTime().format2445());
}
}).start();
MSA
  • 2,502
  • 2
  • 22
  • 35
2

probably you need to use thread.start() instead of thread.run()

thread.start creates a new thread and runs your code in a new thread.

thread.run runs your code in the parent thread, doesn't create a new thread

mmohab
  • 2,303
  • 4
  • 27
  • 43
2

It's because you call sleep in UI thread. Don't ever call sleep in UI thread. You can run stuff on UI thread using Handler.

private static final Handler handler = new Handler();

@Override
protected void onCreate(Bundle state) {
    super.onCreate(state);
    handler.postDelayed(textRunnable, 1000);
}

private final Runnable textRunnable = new Runnable() {
    @Override
    public void run() {
        localTime.setText(LocalTime.getTime().format2445());
        System.out.println(LocalTime.getTime().format2445());
    }
}

Or you can do it working, but the bad way

@Override
protected void onCreate(Bundle state) {
    super.onCreate(state);
    new Thread() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println(LocalTime.getTime().format2445());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        localTime.setText(LocalTime.getTime().format2445());
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();
}
Yaroslav Mytkalyk
  • 16,950
  • 10
  • 72
  • 99
2

You need to start the thread.start()

http://developer.android.com/reference/java/lang/Thread.html

Quoting from the docs

There are two ways to execute code in a new thread. You can either subclass Thread and overriding its run() method, or construct a new Thread and pass a Runnable to the constructor. In either case, the start() method must be called to actually execute the new Thread..

You are calling thread.run(). You are also calling sleep . You should not block the ui thread.

http://developer.android.com/training/articles/perf-anr.html

If you are looking for a count down timer

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

Countdowntimer in minutes and seconds.

You can also use a Handler, timer task. If you use a timer task make sure you udate ui on the ui thread.

Android Thread for a timer

Edit: I failed to notice this. so from the above comments. Credits to DoctorDrive

    localTime.setText(LocalTime.getTime().format2445()); // update ui from thread is not possible

You need to use runOnUiThread

    runOnUiThread(new Runnable() //run on ui thread
             {
              public void run() 
              { 
                localTime.setText(LocalTime.getTime().format2445());

              }
             });
Community
  • 1
  • 1
Raghunandan
  • 132,755
  • 26
  • 225
  • 256