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
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
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.
I'm writing an android app that involves one AudioTrack and one AudioRecord. They run in two different threads, and both of them need to continue to run and not being killed when low memory/CPU even if the app is running in the background. I searched about this and I know I could probably use AsyncTask (just like in music streaming app). However, I'm no exactly sure how to do it because the thread that runs AudioTrack is first created (once a certain button on the main activity is pressed), then this thread will create another thread that runs AudioRecord (by creating a Runnable).
I searched about this and I know I could probably use AsyncTask (just like in music streaming app)
No. Your issue is not the threads, but the process.
both of them need to continue to run and not being killed when low memory/CPU even if the app is running in the background
Strictly speaking, that is not possible. The closest that you will get will be to use a Service that in turn uses startForeground() to indicate that it has foreground priority. That will minimize the probability that Android will terminate your process due to low memory conditions, but it will not eliminate it.
Also, please note that you will need the CPU to be powered on to perform your audio tasks. That, in turn, will require a WakeLock. This is going to seriously hammer the user's battery, to the point where you should advise users to keep the device on a charger. That will be particularly important in the future, where the "Doze mode" of the upcoming "M" Android release will block your use of WakeLocks if the device is idle, unmoving, and not on a charger.
In some games people can cheat by changing the time. For example: when they have to wait 30 minutes before a building is built.
Can i prevent this, assuming that the devices have connection with my server?
I am programming in java using the libGDX library.
Any solutions that work both on IOS and Android?
Store the time they have to wait to on the server (tell the server they perform a task, server will log that time and when they can do it again) and make the client check if the server thinks it can in fact perform the action. Anytime you store something on the client it is likely that there will be a way around it.
Your best bet would be to use SystemClock.elapsedRealtime() as an assistant to an infrequent server side timecheck.
return the time since the system was booted, and include deep sleep. This clock is guaranteed to be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing.
After verifying the time from your server, you can do local checks against SystemClock.elapsedRealtime until the next boot up.
I'm planning on hosting a JRuby on Rails app on Google AppEngine/Java. I found a great blog post by Ola Bini on how to to this, but in the summary he says:
Overall, JRuby on Rails works very
well on the App Engine, except for
some smaller details. The major ones
are the startup cost and testing. As
it happens, you can’t actually get
GAE/J to precreate things. Instead
you’ll have to let the first release
take the hit of this. Now, GAE/J does
a let of preverifying of bytecodes and
so on, so startup is a bit more heavy
than on other JDKs. One runtime takes
about 20 seconds wall time to startup,
so the first hit takes some time.
I don't fully understand this. How often, under what circumstances, will a runtime need to be started up? A regular 20 second lag is likely to be an issue.
App Engine will start new runtimes for you whenever demand is outstripping the currently running instances. It will then shut down instances when demand is lower. Ultimately, this means that all of your instances could be shut down if your app is not used for a certain amount of time. Then, the next time a user tries to access your app, a new instance will need to be started, or "spun up" as some people call it.
As of March, the app engine team wouldn't give any official estimate on how long an instance will stay up:
7:40pm] nwinter: Is it possible to get a rough estimate of how long an app
instance will stick around once spawned?
[7:40pm] marzia_google: #nwinter, not really
[7:40pm] marzia_google: there are no garuntees
[7:41pm] nwinter: No average time or anything?
[7:42pm] marzia_google: #nwinter i'm not sure an average time would be
meaningful, even if i knew off hand what it was ( i don't)
[7:42pm] marzia_google: since it really can be quite variable
[7:42pm] Kardax: Re instance lifetime: So an app instance could last a few
seconds or a few hours? Just curious
[7:43pm] dan_google: nwinter: Apps are evicted by least-recently-used on an
app server. As someone noted recently (forums or chat I forget), low
traffic could mean lots of "restarts", but so could spikes in traffic which
may start new instances on multiple app servers.
[7:43pm] nwinter: #dan_google: good to know!
[7:43pm] dan_google: Kardax: Yes, depending on the weather. By which I
mean, request patterns, other apps on each app server, and so forth. Not
really predictable.
This is the transcript of a chat with the app engine team. I have deleted the non-relevant lines in the transcript like "so and so logged in." The full transcript can be found here