Thread vs AlarmManager which one has low battery usage - java

What I need in my application is do some stuff every 30 sec for 18 hours per day which I want to keep running even device going to sleep mode
for that I found two ways:
Using timer using the AlarmManager with a type of AlarmManager.ELAPSED_REALTIME_WAKEUP
Using a thread with a unfinished while-loop and sleep for thread every 30 seconds.
Now I am using timers, that works fine in all API versions but have one problem and that's battery usage.
My question is, can I use a thread instead of timers? I heard somewhere threads cannot run for very long times (5sec max), but I'm not sure.
And if I can use thread, is that take lower power than timers?
and works for all API versions?

Here is a very good description of your question
http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html

Related

Java ScheduledExecutorService behind the scenes

How does things like scheduleAtFixedRate work? How does it work behind the scenes and is there a penalty to using it?
More specifically, I have a task that I want to run periodically, say every 12 hours. The period is not strict at all, so my first instinct was to check in every request (tomcat server) if it's been more than >12 hours since the task last executed and if so, execute it and reset the timer. The downside of this is that I have to do a small time check on every request, make sure the task is run only once (using a semaphore or something similar) and the task might not execute in a long time if there's no requests.
scheduleAtFixedRate makes it easier to schedule a recurring task, but since I don't know how it does it, I don't know what the performance impact is. Is there a thread continually checking if the task is due to run? etc.
edit:
In Timer.java, there's a mainLoop function which, in my understanding, is something like this (overly simplified):
while(true) {
currentTime = System.currentTimeMillis();
if(myTask.nextExecutionTime == currentTime) myTask.run();
}
Won't this loop try to run as fast as possible and use a ton of CPU (I know, obviously not, but why)? There's no Thread.sleep in there to slow things down.
You can read the code if you wish to work out how it works.
There is an overhead using ScheduledExecutorService in terms of CPU and memory, however on the scale of hours, minutes, second even milli-seconds, it probably not work worrying about. If you have a task running in the range of micro-seconds, I would consider something more light weight.
In short, the overhead is probably too small for you to notice. The benefit it gives you is ease of use, and it is likely to be worth it.

Running thread for 2 millisecond and then wait for particular time before running it again

I have one method execute(data) which takes considerable time (depending on data like 10 seconds or 20 seconds), it has timeout feature which is 30 seconds default. I want to test that method. One way of doing it is to collect enough data which lasts more than 30 seconds and then see whether I get timeout exception. Other way of doing it is to use threads. What I intend to do is to run method for some milliseconds and then put thread on wait before I get timeout exception or make it last for some seconds.Can any one please suggest how can I achieve that.
You should walk through the Java Threads Tutorial (Concurrency). Any answer on Stack Overflow would need to be really long to help you here, and the Threads/Concurrency tutorials already cover this well.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
You could use
Thread.sleep( millis );
to put the thread to sleep for the required time.
Or, you could put your data processing code into a loop, so that it processes it multiple times. This would recreate the scenario of the thread actually processing data for longer than 30 seconds.
Or, you could test your code with a shorter timeout value.

Can I use the Java timer class for timed data collection?

I am writing a program that collects a series of angle inputs during a trial and saves these to a file with their corresponding timestamps.
For example:
1 sec 260 degrees
2 sec 45 degrees
3 sec 60 degrees
etc.
When running a trial, the user should be able to pause and restart or fully abort the trial if need be.
I am running into trouble with the pause functionality. I have been using the Java Timer and TimerTask classes to time the input, as it provides much of the functionality I am looking for (start a task after a delay, only record data at certain intervals, etc.).
Within my timerTask, I have been storing the collected angles and times in parallel arrays, and then at the end of the trial, writing these arrays to a file.
However, when I "pause" my timerTask via the timer.cancel() function and restart it, the old data arrays are thrown away. I have tried to sidestep this issue by saving the "paused" array and then merging it with the "restarted" array at the end of the restarted trial, but this doesn't account for the fact that a trial could be paused numerous times.
Are the timer/timerTask classes the wrong classes to be using for this job? Is there a better way to collect time-based data in Java? Or am I just overlooking a solution?
As the API specifies Timer.cancel()
Terminates this timer, discarding any currently scheduled tasks.
The simplest way to achieve the functionality you desire would probably be to store a 'paused' boolean and toggle it when the user pauses/unpauses. Then check the state of the boolean from within your task and simply return; if the trial is paused. The Timer will still fire every second, but nothing will happen as long as the trial is paused.

Thread sleep is inconsistance in android

I found a surprising things about Thread.sleep. Thread doesn't wake up in time. Let me explain. I create an activity (no service) and run a thread like the following.
Thread.sleep(50000); // 50 seconds
System.out.println("something");
Then i keep the activity in foreground and off the display (by pressing power button). Also i was logging in a file saved in sdcard. What i found that, After almost 10 min Thread delay 7.35 minutes to print instead of 50 seconds. Is it normal?? Can i trust on Thread.sleep()?
16:47:57 ---- START
--------
-------- (all are in time)
--------
16:57:07 -- (in time)
16:57:57 -- (in time)
17:05:38 --- (late)
Can i trust on Thread.sleep()?
You can trust it to behave as specified1. But the specification says that a sleep will cause the thread to stop for at least that number of milliseconds. Under some circumstances, it could stop for longer. For example, if there is a lot of work for a higher priority thread to do, a lower priority thread may not be woken from the sleep for a long time.
1 - Actually, in theory, it might not behave as specified. But you've tendered no evidence to support that ...
You can try:
LockSupport.parkNanos(nanos)
Or other methods it provides. It's more accurate.
I found out that when you turn off the screen using power button then android go to sleep after sometimes. CPU also go to sleep when screen is off. That's whey Thread.sleep() is giving large delay. In my case my device was in sleep mode for 7.30 minute and when i turn on the screen cpu wake up and start the Thread again. By acquiring the Partial_wake_lock you can hold cpu to go to sleep even when you press the power button(not shutdown).
More details

scheduleAtFixedRate slow / late

I'm using a ScheduledExecutorService to provide an update to a database every hour with the scheduleAtFixedRate method. The problem is that it gradually gets later - in long service I've been logging it and it's about a second a day.
I made a small class just to examine this aspect - seems to work fine when nothing is happening on the PC ( running WinXP ) but if things are going on it rapidly gets later. 18:00:00.5 last night was its first log and this morning was 09:00:00.5 then 10:00:05.9, 11:00:26.8, 12:00:45.3, 13:01:07.8...
I can attach the code although my example isn't the smallest.
Anyone else experienced this? Any ideas why this isn't working properly?
I can think of lots of ways around it but I'd really like to know why it doesn't work as advertised!
Thanks, Mike
This is normal AFAIK. With scheduleAtFixedRate, If any execution of this task takes longer than its period, then subsequent executions may start late. That being said, I'd recommend scheduleWithFixedDelay. This will ensure that tasks are carried out at the specified delay interval.

Categories

Resources