I have a timer in my app which shut's down the app implemented with a handler to which I post a delayed runnable "quit". When user clicks the timer icon it should also show how much time is left. How could I get this data?
Should I implement an object which would count the seconds and use that data?
I prefer to use ScheduledExecutorService with ScheduledFuture, these API are more efficient and powerful than Handler and Timer IMO:
ScheduledExecutorService scheduledTaskExecutor = Executors.newScheduledThreadPool(1);
Runnable quitTask = new Runnable();
// schedule quit task in 2 minutes:
ScheduledFuture scheduleFuture = scheduledTaskExecutor.schedule(quitTask, 2, TimeUnit.MINUTES);
... ...
// At some point in the future, if you want to get how much time left:
long timeLeft = scheduleFuture.getDelay(TimeUnit.MINUTES);
... ...
Hope that helps.
Related
I'm working on an app where I have to read data from multiple sensors and send it to a remote server every 15 minutes. This has to be done when the app is closed/killed as well and I also have to be sure it always executes. I also want to be sure it happens (almost) exactly every 15 minutes (+-1 minute difference is the upper limit).
At this point, I've found 3 options: using Workmanager, Alarmmanager or using a foreground service. Following the documentation, Workmanager seems the way to go for background tasks, however, after having done some reading, Alarmmanager seems to be a safer choice (Workmanager sometimes has troubles with doze mode, and the timing isn't exact because it uses a flex period of at least 5 minutes). And a foreground service is not really allowed for this kind of task (it's not really long running, it's just a periodic task) and is being limited in newer Android versions. Do you think it would be a good idea to use an Alarmmanger for this task, or should I use something else? Thanks!
TODO Background scheduling.. You can use this method todo your stuff..
KOTLIN;
val service = Executors.newSingleThreadScheduledExecutor()
val handler = Handler(Looper.getMainLooper())
service.scheduleAtFixedRate({
handler.run {
// Do your stuff here, It gets loop every 15 Minutes
}
}, 0, 15, TimeUnit.MINUTES);
JAVA;
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
Handler handler = new Handler(Looper.getMainLooper());
service.scheduleAtFixedRate(() -> {
handler.post(() -> {
// Do your stuff here, It gets loop every 15 Minutes
});
}, 0, 15, TimeUnit.MINUTES);
I have two handlers running within an Android Service.
handler1 runs every 30 seconds
handler2 runs every 5 seconds
The problem is, handler2 can't run at the same time as handler1.
I mean, when handler2 reaches 30, 60, 90... secs it will run at the same time as handler1.
So, I need to find a way during those 30, 60 90 secs to run one handler after another.
I know a solution for this could be, but it's not elegant, neither accurate:
Run handler1 at second 0
Wait 7 seconds (or any other x # of secs no-multiple of 5)
Since handler2 runs more frequently than handler1 does, you can use counter in handler2 to track when to fire the events that you plan to trigger in handler1.
handler2.postDelayed(new Runnable() {
int count = 0;
#Override
public void run() {
if (count == 0) {
// fire handler1 events
}
count = (count+1) % 6;
}
}, 5);
How about using TimerTask and Timer to schedule repeated executions (every 5 seconds)? Depending on the interval, you run either the job currently done in handler1, or the one in handler2, or both. Perhaps you can break out these jobs into functions that are called from the TimerTask's run method. That would let the handler1 job run before the handler2 job, in a synchronized manner on the same thread.
new Handler().postDelayed(new Runnable() {
public void run() {
//code
}
}, secondsDelayed * 1000);
here even if change value of 1000 to 100 or 10 thread runs for min 1sec.
This method postDelayed, has second parameter to let it know , in how much time it should start to run. not for how much time it should run, See Method info below
public final boolean postDelayed (Runnable r, long delayMillis)
Since: API Level 1
Causes the Runnable r to be added to the message queue, to be run after the
specified amount of time elapses. The runnable will be run on the thread to which this handler is attached.
Parameters
r The Runnable that will be executed.
delayMillis The delay (in milliseconds) until the Runnable will be executed.
Returns
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting. Note that a result of true does not mean the Runnable will be processed -- if the looper is quit before the delivery time of the message occurs then the message will be dropped.
** Please also include "What you want to do" so one can also provide other possible solutions :)
I can run codes after every x seconds, but is there a way to only run a code once after x sec? Ex: I want to refresh a listview once after 1 second when a user click on a button?
Since the delayed operation is a UI Event, use a Handler
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//my events
}
}, 2000); //time in millis
I usually recommend
Timer
class in time related stuffs. but in this case i wont recommend you to use Timer as you need to execute the operation only one.
Why not simply use a
Thread
and sleep it for 1000 millis. There you go. your 1 sec timer. :)
Hello I have a ActionScript 3.0 project and I have a timer that is running on 1000 millisecond intervals. I would like to delay this timer for 1500 milliseconds perform an action and start the timer again after the delay. I thought I could do this easily, but I'm having trouble, would it be better to stop the timer and perform the action and then listen for the action to be completed to start the timer again?
If you have time, I would appreciate the help.
Thank you,
Scientific
Assuming I understood your question, why not something like this? (UNTESTED CODE)
yourTimer.addEventListener(TimerEvent.TIMER, itIsTime);
function itIsTime(evt:TimerEvent):void {
yourTimer.stop();
yourTimer.reset();
if(yourTimer.delay == 1500){
//Do your stuff
...
yourTimer.delay = 1000;
yourTimer.start();
} else {
//Do your stuff
...
yourTimer.delay = 1500;
yourTimer.start();
}
}
Alternatively you could use 2 timers, but the idea is the same, after 1000 do one thing, after 1500 do something different, controlling when each timer goes off with the other timer's listener function.