TiagoM
TiagoM

Reputation: 3526

Updating UI using a Handler freezes my app

I am trying to make a clock, using a TextView :)

Someone here told me that I couldn't use normal threads to change the UI, but Handler or AsyncTask. I managed to get it working a few days ago, but was not a consistent thread.

Now what I want is a consistent thread that is always changing the text of my Textview. I tried using this, but didn't work, any help?

private void startClock() {
    new Handler().postDelayed(new Runnable(){

        @Override
        public void run() {
            while (true) {
                final long millis = System.currentTimeMillis() - MainActivity.startedAt;
                clock.setText("" + millis);
                runOnUiThread (new Runnable() {

                    @Override
                    public void run() {
                        clock.setText("" + millis);
                    }
                });

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }, 2000);
}

Upvotes: 0

Views: 2374

Answers (2)

Moog
Moog

Reputation: 10193

Look here for an example https://stackoverflow.com/a/11140429/808940

Also note that you have a duplicate line in your code:

clock.setText(""+millis);

It appears both in the runOnUiThread and in the main handler, it should only appear in the runOnUiThread runnable

Upvotes: 2

lenik
lenik

Reputation: 23538

you should get rid of:

while(true) {
    ....
    sleep(1000);
    ...
}

because this get your thread stuck forever. your program should work like this:

private Handler mHandler = new Handler();

@Override
public void onResume() {
    super.onResume();
    mHandler.removeCallbacks(mUpdateClockTask);
    mHandler.postDelayed(mUpdateCLockTask, 100);
}

@Override
public void onPause() {
    super.onPause();
    mHandler.removeCallbacks(mUpdateClockTask);
}

private Runnable mUpdateClockTask = new Runnable() {
    public void run() {
        updateClock();
        mHandler.postDelayed(mUpdateClockTask, 2000);
    }
};

and inside updateClock() you do all your UI updates.

Upvotes: 4

Related Questions