I've seen a number of questions using the Handler or Timer implementations in Android apps to delay an update to the UI thread. Most of these seem to be short - a few seconds at most.
Are there issues with using a 24 hour delay for a task? How does Android handle very long running Hander and Timers?
Are there issues with using a 24 hour delay for a task?
It won't work reliably.
A Handler, or any other in-process timing option (e.g., ScheduledExecutorService) is only as good as the process that is hosting it. Once the process goes away, so does the timing. Android processes normally do not live for 24 hours.
If it makes you feel any better, all the other alternatives (e.g., AlarmManager, JobScheduler) will also not work reliably as of Android M, in the interests of power management. However, the alternatives will be efficiently unreliable, since they do not require your process to be constantly running.
Related
I'm developing an application where i need to execute a countdown, have a certain counter go down every second, and display in a widget.
No problem, that is done easily using the java class javax.swing.Timer, but the performance are poor.
There are other graphical object on screen and it is not accurate enough, letting it go down from 10 minute to 0 takes more than 10 minutes.
First thing i tried is a Timer with a 1000ms delay, that makes me lose a lot of seconds and sometimes it is not fast enough in updating the view.
Second, i tried with a Timer with a delay of 20ms and a logic inside that let my action run only if the System.nanoTime() report a second from last execution.
This gives me a better accuracy, but yet in an environment where the java application is in execution with other applications on old systems, it performs even worse.
Is there a way to achieve a scheduler indipendent Timer in Java?
I'm up for really anything. OS indipendence isn't really an issue, so native code is an option if it gives me a good result.
UPDATE:
I created an example and uploaded it on gist:
https://gist.github.com/bracco23/c160c9591ac216a2eb9452ef9e7d6d95
Badly, the example isn't really as bad as the full project, i let it run for the full 10 minutes and it took about 602s, a 2s delay that's less than 0.4%, not really bad, i wouldn't mind that.
I'm uploading it to show the schema of the application, the same in the example and in the full application.
thank you very much anyway :D
I have several threads in my Android application that should be executed concurrently. I am not running them on several cores. REAL parallel execution at exactly the same time is not necessary. If Android switches between the different tasks or temporarily pauses certain threads, it's Ok.
The problem: Some threads are highly time consuming and computationally expensive (complex algorithms), but are not real time critical. Other threads and the Android UI thread are real time critical and should not be blocked or heavily delayed by the time consuming processes. Nevertheless, the time consuming processes should also be executed if there are no other more important tasks to perform. Ideally, the highly important threads should safely pause the less important threads. In Java people used to implement suspend() commands, but they are now depricated.
What is the recommended way to solve this problem in Android?? In Java I would have used Sleep commands or wait and notify methods. What is recommended way in Android?
Thanks for the anwer, guys!
Edit:
I was thinking about threads. But I wrote "processes" instead of "threads", just in case regular threads are not the best way to solve the problem in Android. I am open to anything. I have only ONE App. Sorry if terms get mixed up a little. But I wanted to keep the options and ideas open.
Thanks for the comments and answers so far. But I am more interested in a GENERAL, recommended, established strategy and good practice to solve this kind of problem in Android. I could also do some hacks, but I was really hoping for a clean and established solution. I am more looking for an answer like: "The common, established approach is to use strategy A + strategy B..."
In my opinion you should use a different component (Service) and set it to run on a different process - here you can see how
By doing so you can put all the computing in a different process that not related to your man UI component lifecycle.
If the dependency of algorithms' logics and the main UI is loose I wouldn't try to implement them via Threads concurrency.
It has come to my attention that Android 5.1 no longer accepts recurring alarms for time intervals shorter than 60 seconds (source).
I am developing an application that logs information about wireless networks. For the operation of the application it is imperative that it can perform its operations every 1-2 seconds and that it doesn't get killed or suspended by the operating system even if it is using a lot of resources. Reliable operation over long periods of time (several hours) is the most important thing. Impact on battery life is not a concern.
So far the most reliable way of achieving this functionality has been to use recurring alarms. Now with Android 5.1 that is no longer an option. What would be my best options for replacing the AlarmManager implementation?
As a workaround you can set up 60 alarms to get flexible solution for your current implementation. Check OS version and set up as many alarms as you need.
But for a long-term solution I suggest you to implement sticky foreground service which would work similar to music player. Something simple like Handler.postDelayed should be enough to keep it alive. The reason to do this way is that alarms are not accurate and it is always better to have some control on the process.
In my Android app, I need a certain bit of code to execute every minute, whether the phone is active or not.
(For those curious, the app is meant for a personal project, a "talking" clock which will need to check every minute if that time has a corresponding sound file to play. It's not something I plan to release to the world, so battery considerations are not in play.)
My current approach is to use Timer.scheduleAtFixedRate() to schedule a task.
This seems to work whenever I am looking at the app, and interacting with it occasionally to keep the screen from blanking, but if the phone turns the screen off to save power, it seems like my call happens sporadically.
I tried setting the interval to be every 30 seconds, but even then it seems like I miss some minutes. Are there specific considerations to using Timer on Android? Is there a better way to achieve what I need?
Question: are you 100% absolutely sure you need to be doing this every minute? It just sounds to me that you'll be hogging the battery like crazy and will get quite a few unhappy users.
But if you answer yes to that question:
After your activity is paused, there's not guarantee from the system that anything on it (including your task) will be kept running; that way as soon as the systems needs a couple of megabytes to do anything it will kill your activity and stop your timer.
You should implement the timer/task in a Service. Services are much less likely to be killed by the system and you might ask that if the system needs to kill it to re-created it as soon as possible.
Have you tried using AlarmManager, this will let you do a task every X amount of time even if the phone is in standby mode or off
Here are the docs for it
If you want a nice example of using an AlarmManager, here it is... This one does not work if the phone is turned off but you can enable this easily if you want
I use java.util.Timer to trigger jobs in my app, but I found that it is depend on system time: if system time is adjusted, timer's trigger will be affected.
For example, if system time goes back by 80 seconds, the timer will stop working for 80 seconds.
Java has a System.nanoTime method which is independent of system time, but it seems that it
cannot be used in Timer.
Is there Timer library that supports what I need? Or I have to implement it myself?
Notice that I don't need a precise current time(date), I need a precise time interval
you have 2 options:
Write your one timer, relatively trivial. Before anyone tell reinvent the wheel, being able to carry the task yourself is always important. Especially when it's around 20 lines of code.
Use java.util.concurrent.ScheduledThreadPoolExecturor and use scheduleAtFixedRate, the queue impl. is based on System.nanoTime.
Install ntp daemon that adjusts the time by tuning (slowing down, speeding up) the system clock in very slight fashion during long time span.
Few other things, perfect 100ms is a tall order in non-real time GC environment as GC may STW (stop the world) for seconds sometimes. Sun's GCs can't do that super reliably. IBM's Metronome running on modified Linux kernel is supposed to be able to. You may wish to pay attention to if your application is truly real-time demanding.
If your computer is isolated and off the Internet i think there is not much you can do if the user tampers with the clock.
On the other hand, if this is not the case, you will find quite many API's and Mashups that will allow you to read the correct time. You could read the time from there. You could read the time from time.gov. Also twinsun.com you give you lots of additional options.
100ms seems like too low for Internet time-access.