Android - loop part of the code every 5 seconds

49,785

Solution 1

Using a CountDownTimer as in one of the other answers is one way to do it. Another would be to use a Handler and the postDelayed method:

private boolean started = false;
private Handler handler = new Handler();

private Runnable runnable = new Runnable() {        
    @Override
    public void run() {
        final Random random = new Random();
        int i = random.nextInt(2 - 0 + 1) + 0;
        random_note.setImageResource(image[i]);
        if(started) {
            start();
        }
    }
};

public void stop() {
    started = false;
    handler.removeCallbacks(runnable);
}

public void start() {
    started = true;
    handler.postDelayed(runnable, 2000);        
}

Here's an example using a Timer and a TimerTask:

private Timer timer;
private TimerTask timerTask = new TimerTask() {

    @Override
    public void run() {
        final Random random = new Random();
        int i = random.nextInt(2 - 0 + 1) + 0;
        random_note.setImageResource(image[i]);
    }
};

public void start() {
    if(timer != null) {
        return;
    }
    timer = new Timer();
    timer.scheduleAtFixedRate(timerTask, 0, 2000);
}

public void stop() {
    timer.cancel();
    timer = null;
}

Solution 2

You can use CountDownTimer as the following method:

private CountDownTimer timer;

timer = new CountDownTimer(5000, 20) {

    @Override
    public void onTick(long millisUntilFinished) {

    }

    @Override
    public void onFinish() {
        try{
            yourMethod();
        }catch(Exception e){
            Log.e("Error", "Error: " + e.toString());
        }
    }
}.start();

And then to call the timer again:

public void yourMethod(){
    //do what you want
    timer.start();
}

To cancel the timer, you can call timer.cancel();

Hope it helps!

Solution 3

You can use RxJava2/RxAndroid2 and create an Observable that emits a message every second (or whatever you want), example with pseudo code:

Disposable timer = Observable.interval(1000L, TimeUnit.MILLISECONDS)
            .timeInterval()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Timed<Long>>() {
                @Override
                public void accept(@NonNull Timed<Long> longTimed) throws Exception {               
                    //your code here.
                    Log.d(TAG, new DateTime());
                }
            });

When you want to stop it, you can simply call:

timer.dispose();

I find this code much more readable than the other options.

Share:
49,785
Damijan
Author by

Damijan

Updated on June 21, 2020

Comments

  • Damijan
    Damijan almost 4 years

    I would like to start repeating two lines of code every 5 seconds when I press the button START and end it, when I press the button STOP. I was trynig with a TimerTask and Handles, but couldn't figure it out how.

    public class MainActivity extends Activity {
    
    
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
               //final int i;
               final TextView textView = (TextView) findViewById(R.id.textView);
               final Button START_STOP = (Button) findViewById(R.id.START_STOP);
               final ImageView random_note = (ImageView) findViewById(R.id.random_note);
               final int min = 0;
               final int max = 2;
               final Integer[] image = { R.drawable.a0, R.drawable.a1,R.drawable.a2 };
    
    
    
            START_STOP.setTag(1);
            START_STOP.setText("START");
    
    
            START_STOP.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                int status = (Integer) v.getTag();
                if (status ==1) {
                    textView.setText("Hello");
                    START_STOP.setText("STOP");
                    v.setTag(0);
    
                    final Random random = new Random();
    
                                    //************************************************************
                    // I would like to loop next 2 lines of code every 5 seconds.//
    
                                    int i = random.nextInt(2 - 0 + 1) + 0;
                    random_note.setImageResource(image[i]);
    
                    //************************************************************
                        }
    
                else
                {
                    textView.setText("Bye");
                    START_STOP.setText("Let's PLAY!");
                    v.setTag(1);
                }
    
    
                }
            });     
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
    
    }
    
  • Giacomoni
    Giacomoni about 10 years
    I have always used a CountDownTimer in my apps, like to change the banners in an activity every 5 seconds. What's the best way to repeat some action every 5 seconds, the CountDownTimer or the Handler and postDelayed?
  • Damijan
    Damijan about 10 years
    Thanks. Where would you put that in my original code?
  • britzl
    britzl about 10 years
    Good question giacomoni! I had a look at the CountDownTimer and it uses a Handler internally: grepcode.com/file/repository.grepcode.com/java/ext/… so I guess they are more or less equivalent. The Timer uses a TimerThread with a queue of TimerTasks: grepcode.com/file/repository.grepcode.com/java/root/jdk/open‌​jdk/… It's hard to say which one is better. I don't know enough about the differences between threads and handlers to give you a good enough answer.
  • britzl
    britzl about 10 years
    @Damijan Put the start and stop methods somewhere in your activity. Call them from the onClick() method depending on button state. Put the TimerTask or the Runnable inside your activity as well as normal member variables of the Activity
  • Admin
    Admin over 7 years
    hello sir, can the above code be used to refresh an activity until the user clicks back button...?