Bresug Cosmin
Bresug Cosmin

Reputation: 5

Update a textView in real time (using a for)

So I have an android app where I want to decrement a value and display it in a textview. I start from 1000 and decrement it by 1 from 1 to 1 seconds. This acts as a score that decreases in time if you stay more on the level. This is my code:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.game);
    timeText = (TextView) findViewById(R.id.textView5);



    runOnUiThread(new Runnable() {
        @Override
        public void run() {

            for(time=1000;time>=0;time--){
                try {
                    TimeUnit.SECONDS.sleep(1);
                            timeText.setText(String.valueOf(time));
                            System.out.println(time);

                }


                catch(Exception e)
                {
                    System.out.println("Error on delay");
                }

            }}
        });

 }

My error is that whenever I enter this activity, the screen turns black. The console is printing the values from second to second and if i comment the "for" the textView displays properly the value 1000 (if i declare int time = 1000 of course). I am really not sure what the problem is here. Does somebody know what i'm doing wrong?

Upvotes: 0

Views: 2321

Answers (2)

Salman Tariq
Salman Tariq

Reputation: 353

You are pausing the UI in that for loop.

To achieve what you want, either use a Handler

new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //update textview here
        }
    },1000);

OR

use a Timer

new Timer().scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            //update
        }
    },1000,0);

I don't know much about handlers but you don't need a for loop in timer.

In your case:

  long time=1000;

  new Timer().scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable(){
                 timeText.setText(String.valueOf(time))
                 time--;
            });
        }
    },1000,0).start();

Good luck

Upvotes: 0

Gabe Sechan
Gabe Sechan

Reputation: 93668

You can't just loop on the UI thread like that. Inside Android there's a message loop on the UI thread. When it needs to draw, it sends a message to that message loop. Until you process that message the changes won't appear on screen. And to process a message, your code must finish and return to the message loop.

If you want to do this, you can't use a for loop on the UI thread. You need to send individual messages to a Handler for each draw you want to make.

Upvotes: 1

Related Questions