Android - loop part of the code every 5 seconds
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.
Damijan
Updated on June 21, 2020Comments
-
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 about 10 yearsI 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 about 10 yearsThanks. Where would you put that in my original code?
-
britzl about 10 yearsGood 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/openjdk/… 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 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 over 7 yearshello sir, can the above code be used to refresh an activity until the user clicks back button...?