djmloody27
djmloody27

Reputation: 45

Counter in loop

How to do sample counter in Activity? This is not working.

public class MainActivity extends AppCompatActivity implements Runnable {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        run();
    }

    @Override
    public void run() {
        while (true) {
            updateTv();

            try {
                Thread.sleep(17);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void updateTv() {
        int counter = 100;
        final TextView tv = (TextView) findViewById(R.id.tv);
        tv.setText(String.valueOf(counter));
        counter--;
    }
}

Upvotes: 1

Views: 283

Answers (2)

Tomasz Dzieniak
Tomasz Dzieniak

Reputation: 2915

Consider using Timer class which allows you to define a callback method that will be invoked at specified rate.

An example that fits your needs:

public class CounterActivity extends AppCompatActivity {
    private TextView mCounterTextView;
    private Timer mTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_counter);

        mCounterTextView = (TextView) findViewById(R.id.counterTextView);

        mTimer = new Timer();
        mTimer.scheduleAtFixedRate(
            new CounterTask(100), 0, TimeUnit.SECONDS.toMillis(1));
    }

    protected class CounterTask extends TimerTask {
        protected int mCounter;

        CounterTask(int initial) {
            mCounter = initial;
        }

        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mCounterTextView.setText(String.valueOf(mCounter));
                }
            });

            --mCounter;
        }
    }
}

One more thing that should be noticed. As Timer executes it's own thread - it prevents you from updating your UI from outside of the main thread. In that case you have to register a Runnable using runOnUiThread method.

Also, calling findViewById in a loop is not the best idea.

Upvotes: 1

tynn
tynn

Reputation: 39843

In onCreate() you're starting an infinite loop inside of the UI thread, blocking it completely. Alternatively you could use a Handler for periodic updates. Maybe using a bigger delay and stop it sometime.

public class MainActivity extends AppCompatActivity implements Runnable {
    private final Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        run();
    }

    @Override
    public void run() {
        updateTv();
        mHandler.postDelayed(this, 17);
    }

    public void updateTv() {
        int counter = 100;
        final TextView tv = (TextView) findViewById(R.id.tv);
        tv.setText(String.valueOf(counter));
        counter--;
    }
}

Anyway you should read What is the Android UiThread (UI thread) for sure.

Upvotes: 4

Related Questions