Repeat a Task With a Time Delay

Repeat delayed task n times

 import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
class RepeatableTask extends TimerTask{
int repeats;
Timer time;
public RepeatableTask(int repeats){
this.repeats=repeats;
}
void init(){
time = new Timer();
time.schedule(this,0,TimeUnit.MINUTES.toMillis(delayInMinutes));
}
void stop(){
time.cancel();
}
void run(){
if(repeats == 0){stop();}
new Thread->{
//task
}
repeats--;
}
}

//usage
RepeatableTask taskObject = new RepeatableTask(5);
taskObject.init();

Repeat a task within a duration with delay

so what you are doing here is simulating progress. Ideally, there would be some way of checking the actual progress of your bar, and updating it, and when it is done, ending. But, if this is not possible, then ya, simulation is your choice.

So, with coroutines we are dealing with a threaded environment, and within that, we have our coroutines which need to be continued when the hand over control of execution. In your implementation, this happens at the delay call. For this reason, it is very difficult to guarantee that your coroutine will complete in your desired time. All delay can do is say that it will not resume before "at least" the specified time has elapsed, and probably quite often, more time would have elapsed, not the exact time.

So, how do we get this to execute in as close to your desired time frame as possible? What we need to do is drop the repeat, and rather check on the elapsed time to decide if we finish. Here is a rough implementation that will hopefully help.

class Bar(val barLength: Int = 1000) {
var progress = 0
}

suspend fun simulateProgress(bar: Bar, job: Job, totalDurationMillis: Long, incrementsMills: Long): Job {
var startTime = System.currentTimeMillis()
return CoroutineScope(Dispatchers.Default + job).launch {
var totalElapsed = 0L
while (totalElapsed < totalDurationMillis) {
totalElapsed = System.currentTimeMillis() - startTime
val progressRatio = totalElapsed.toDouble()/totalDurationMillis.toDouble()
bar.progress = (progressRatio * bar.barLength.toDouble()).toInt()
delay(incrementsMills)
}
println("Elapsed: $totalElapsed, Progress: ${bar.progress}")
}
}

fun main() = runBlocking {
val job = Job()
val bar = Bar()
val progressJob = simulateProgress(bar, job, 6000, 10)
progressJob.join()
}

Repeat a task with a time delay inside a custom view

The following example shows how to set a repeating task on a custom view. The task works by using a handler that runs some code every second. Touching the view starts and stops the task.

public class MyCustomView extends View {

private static final int DELAY = 1000; // 1 second
private Handler mHandler;

// keep track of the current color and whether the task is running
private boolean isBlue = true;
private boolean isRunning = false;

// constructors
public MyCustomView(Context context) {
this(context, null, 0);
}
public MyCustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init() {
mHandler = new Handler();
}

// start or stop the blinking when the view is touched
@Override
public boolean onTouchEvent(MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_UP) {
if (isRunning) {
stopRepeatingTask();
} else {
startRepeatingTask();
}
isRunning = !isRunning;
}
return true;
}

// alternate the view's background color
Runnable mRunnableCode = new Runnable() {
@Override
public void run() {
if (isBlue) {
MyCustomView.this.setBackgroundColor(Color.RED);
}else {
MyCustomView.this.setBackgroundColor(Color.BLUE);
}
isBlue = !isBlue;

// repost the code to run again after a delay
mHandler.postDelayed(mRunnableCode, DELAY);
}
};

// start the task
void startRepeatingTask() {
mRunnableCode.run();
}

// stop running the task, cancel any current code that is waiting to run
void stopRepeatingTask() {
mHandler.removeCallbacks(mRunnableCode);
}

// make sure that the handler cancels any tasks left when the view is destroyed
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopRepeatingTask();
}
}

Here is what the view looks like after being clicked.

Sample Image

Thanks to this answer for ideas.

How to repeat a task after a fixed amount of time in android?

Set repeated task using this:

//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {

@Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}

},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);

and if you wanted to cancel the task simply call t.cancel() here t is your Timer object

and you can also check comment placed below your answer they have given brief information about that.

Repeat a task with time delay in WinJS

If Im reading this correctly and you simply want to do this while the application is running you just need a javascript timer - setTimeout.
note that with setTimeout you pass in the function itself without parenthesis, not a string name. Here's an app sample with a timer that updated the UI, although the main important takeaway here is that you need to make sure you call setTimeout again from within your 'update' function. Check out that code here

If you want some sort of background task to do this and generate a separate image (I dont think thats what you ant, but I'll include that since we're talking about tasks and delays)

If you are using Windows 8.1 (which releases soon) you can use the new scheduler class and pause and resume every 30 seconds as shown here

If you are using Windows 8 (and will work on 8.1) you can if I recall correctly setup your scheduled tasks every fifteen minutes and create one shot tasks for each 30 seconds within that time. run background task on timer

Repeated Tasks using Timer Interval vs Task Delay

Method A is used when you have to trigger some task at regular intervals. Method B is used when you have to give regular intervals between the triggering of some task.

There is a difference if the event handler (task performed after the trigger) takes a longer time to process.

Method A :
No matter how much time the task in the event handler takes, the event handler keeps getting triggered at the set time interval (code has to be reentrant).

Method B :
Task completes then we sleep. So if the task takes different times to complete, the next trigger is also at different times

Using a handler to delay a repeated task for a limited number of times

There are a number of ways to do this, including something like what you have done here. The first thing to do is remove the while() loop at the end of your Runnable and instead just have the Runnable post itself as long as the count is less than 49. What you have now is posting the same Runnable multiple times each time it is run, all triggered to be delivered at the same time to the main Handler.

Android Handler for repeated task - will it overlap ? Timer-task VS handler VS alarm-manager

I decided to answer my own question since I've found out how to do it right way. The Android way. First of all what I was trying to do and posted in the question is a wrong approach to my requirement. Now I'm posting this so someone else will not do it wrong way but the following way.

Android has few options for timing.

  1. Timer-task -> runs while application is alive. best for short term timing. Resource usage is higher.

  2. Handler -> runs while application is alive. But not suitable to used as a scheduler. (this is what I've asked and it's not the correct way to do that). Handlers are the best way to do something repeatedly till the app is killed.

  3. Alarm-manager -> The best way to schedule something to happen in future even if the app is killed. (this is what I should apply for my app).

This is what I figured out. Correct me if I'm wrong.

How to loop through timer class for delayed time?

To run a timer for n seconds you can use CountDownTimer

Declare two varibales globbaly. One for number of times you want to repeat. and one to keep the count of repetaion.

 private int NUM_REPEAT = 4;
private int REPEAT_COUNT = 0;

Then call this method wherever you want. One thing to note if you want to run this loop 5 times you have to give number of repeation 4. Cause to satrt this function you have to call it so that will not come in count.

private void startTimer() {

new CountDownTimer(3000, 1000) {
int secondsLeft = 0;

public void onTick(long ms) {
if (Math.round((float) ms / 1000.0f) != secondsLeft) {
secondsLeft = Math.round((float) ms / 1000.0f);
// resend_timer is a textview
resend_timer.setText("remaining time is "+secondsLeft);
;
}
}

public void onFinish() {
Log.d(TAG, "timer finished "+REPEAT_COUNT);
if (REPEAT_COUNT <= NUM_REPEAT) {
startTimer();
REPEAT_COUNT++;
}

}
}.start();
}


Related Topics



Leave a reply



Submit