What are the performance implications of disabling the lock-screen? - android

I am working on a timer application (it's my first app to try and learn the ropes). While the timer is running, I want to offer the user the ability to prevent the screen from locking.
Since the screen is always displaying something (and refreshing the clock every second), what would the performance penalty be for doing this? The only things active on the screen are the timer (black background with just the running time) and "split" and "stop" buttons? I am mostly concerned with the battery life of the phone; e.g. if this were a long-running timer job (let's say long-distance running with split times).

I have used both an iPhone and an android for running apps in the past. The first iPhone versions couldn't 'lock' the screen because it disabled the GPS too. Leaving the screen on, even with minimal backlight, absolutely ruins battery life, because the backlight and screen-refresh operations are quite expensive. Battery life went up from ~30 minutes to ~5 hours when running with the screen off.
There are some innovative solutions to this for runners, for example RunKeeper (and I'm sure most of the other ones too) has an option to fade the music out and give you updates on your stats every n minutes.

Related

Performance in the background with Foreground Service and wake lock is significantly slower on Samsungs

We’ve noticed that our app in the background behaves differently on different vendors’ devices. Basically, while the app is in the foreground state everything works very well, our processing takes around 15-50ms per frame so the system is very responsive, but very soon after a user moves our application to the background state we are starting to experience a delay in processing, it starts to take significantly more time (up to 600 - 800ms per frame)
So the question is, can we do something to improve performance background performance on Samsungs?
Maybe to be prioritized or to be whitelisted, or not be pushed to a low-level CPU.
We have developed a small application to investigate this issue.
Here is the link for them who'd like to try: https://drive.google.com/file/d/1DVJ9F3jDEW5AO8CSA_8znRupiQiBB10M/view
This app has foreground service, wakelock, and a simple “heavy” operation that basically does this:
private var array = DoubleArray(100) { 0.0 }
while (i < 1_000_000) {
array[abs(k % count)] = Random.nextDouble() * i
i++
k++
}
The results that we got after some testing were familiar with what we’ve been having in our app.
On Samsung devices (Samsung S22) with Android 12 time for processing in the foreground was fast and almost constant (160-180ms), but after ~10 seconds when the app is in the background time for processing is drastically going up to 1100-1120ms, compared with Pixel 6 with 180-190ms in foreground and 300-350ms in the background. So time for processing on Samsung increased 5 times in the meantime on Pixel it was ~2 times or even less. In addition to that, we saw that the app was pushed to low-performant CPU-s in the background and returned back to the foreground, but on the Pixel device, the app was never pushed lower 4th CPU. All the tests are made on the devices with no other active applications running in parallel with us.
Below are the sample app' profiler screenshots that show how differently it behaves on Pixel (1 pictire) and Samsung(2 picture):

Not releasing MediaPlayer causes battery drain

I'm working on an app that uses a MediaPlayer object to play H.264 MP4 videos from a WallpaperService as it is a live wallpaper app. Battery drain occurs while the device (Nexus 5, Android 6.0.1) is idle and sleeping if I pause/stop the MediaPlayer with mediaPlayer.pause() or mediaPlayer.stop(). The drain is about 3-7%/hour as tested multiple times overnight. As soon as I release the media player with mediaPlayer.release(), the battery drain goes back to a more normal 1%/hour. I pause/stop the mediaPlayer when onVisibilityChanged calls false. The phone is reporting to be going to sleep in both the stock Android battery chart and Better Battery Stats.
How can this battery drain be explained if the CPU is going into a sleep state successfully?
EDIT: Something new I've discovered is that when calling mediaPlayer.setSurface(null) right before mediaPlayer.pause(), the idle battery use comes back to normal. I can then do mediaPlayer.setSurface(surface) to set it back before mediaPlayer.start(). The problem is there's some black artifacting for a couple of seconds after restarting.
I can't give you a precise answer but can give you what to look for. I suspect what is going on is that pause() is checking for events frequently enough to keep the processor from entering the deeper sleep/C-states. In contrast, stop() doesn't need to check for events and so allows the processor to enter a deep sleep state. I wrote an article on sleep states some years back.
I suspect that the writers of the function decided to check more frequently than is necessary. This is a very common mistake due to the developers thinking that shorter sleeps / more frequent checking result in better response (which it almost never does). You can check this by using a processor power monitor that actually checks the hardware sleep states. Unfortunately, most don't and only check for processor independent "equivalents".
So let's get back to your question: What can you do about it. I can give you some advice but none of it is very satisfying:
Check for an API or data structure that allows you to set the
checking interval for pause(). By the way, I don't know of any.
Write your own. Of course, this complicates writing platform independent apps
Use an alternative media player that has done this correctly
Hammer on google until it's fixed
Like I said, none of this is very satisfying. By the way, searching the net, I found evidence that this has happened more than once with new Android releases.
Good luck and let us know what happens.

Android thread performance/priority on Galaxy Note 2 when screen is touched/released

I have an OpenGL game for Android. It runs at a good 60fps when the screen is touched. When I release my finger it goes back down to around 30fps. Does the touch event/release raise/lower a thread's priority and if so how can I replicate this to keep it at a constant 60fps. This only seems to be an issue on Galaxy Note 2 so far.
I'll assume you are using onDrawFrame and setRenderMode(RENDERMODE_CONTINUOUSLY).
30 and 60FPS indicates that your implementation of onDrawFrame is called as the device's screen refreshes. Most displays refresh at 60Hz, giving you 60FPS.
It is likely that the Galaxy Note 2 has some power saving feature that limits screen refresh to 30Hz when there are no touches on screen. Check if there's any way to disable this feature.
AFAIK, OpenGL ES does not specify a standard for screen refresh rates, you will need a throttling function to ensure that your game runs/feels the same (i.e. at the same speed) despite differences in FPS.
Yes.
The best way to observe this phenomena is to use systrace with the "freq" tag enabled. You probably need a rooted device, and you definitely need one on which systrace is enabled.
systrace will record changes in the clock frequency for various components. It varies by device, but you can usually get the per-core CPU clocks and GPU memory rate. You will likely see several of them drop significantly at the same time your frame rate drops.
The motivation for doing this is to reduce power requirements and extend battery life. The assumption is that, while your finger is in contact with the screen, you're actively doing something and the device should be as responsive as possible. After a brief period of time, the clocks will slow to a level appropriate for the current workload. The heuristics that determine how long to wait before slowing, and how much to slow down, are tuned for each device.
(This has caused some people to create a thread that just sits and spins on multi-core devices as a way to artificially prop up the CPU clock rate. Not recommended. See also this answer.)
The bottom line is that this isn't a simple matter of adjusting thread priorities. You have to choose between recognizing that the slowdown will happen and adapting to it (by making your game updates independent of frame rate), or figure out some way to fool the device into staying in a higher-power mode when you want smooth animation.
(For anyone who wants to play along at home: build a copy of Grafika and start the "Record GL app" activity. If you drag your finger around the screen all will be well, but if you leave it alone for a few seconds you may start to see the dropped-frame counter rising as the app falls behind. Seen on Nexus 5, Nexus 7 (2013), and others.)

Best Android threading technique for long-running tasks?

The thing is, that I have to keep a thread running for a pretty long time (it's really an indefinite time, could be 1 minute or even months), and it needs to update the UI about once every 1 milisecond...
There is the Executor, AsyncTask, Handler and the native Thread class... but which one is better for this case?
The problem with AsyncTask is that it is destroyed (or detached from the Activity?) like one hour or so after the Activity starts running on background, and the user could return to the Activity at any time just to find that it's not working (and even causing memory leaks), and the UI lags when changing to another activity or even pulling down the notification panel.
Natural Threads are even more laggy due to the post() method being called on the TextView every time I need an update to the UI (remember that I need to report progress about once every 1 milisecond)...
tl:dr
I'm developing a long running stopwatch, that can measure from miliseconds to days, weeks or even years. What is the best UI-intensive threading technique for this?
Could you please help me? Thanks!!
--- Edit:
Solved. It had to do something with system resources and the app moving to background. I just had to save the inital time and pauses as a bundle and load them when the app is started again. Thank you everyone!
I'm no Android expert, but I'm guessing that the reason why your AsyncTask gets cancelled is because the OS, being a battery powered OS, is deciding that a long running background task is a bad thing for battery consumption.
Having your program run a background thread for years is going to be a big disappointment for your users who will wonder why their mobiles run out of juice within a couple of hours. I suggest finding another way of doing your time measurement. What's wrong with using the device's real time clock?
I see little point in trying to update a GUI once every millisecond. The OS isn't refreshing the screen at that rate anyway, and no user on earth is going to notice anyway. Plump for once every 40ms at most.
And then there's the matter of accuracy. There's no point trying to measure time with millisecond precision on a device like an Android mobile over periods of hours, never mind days or months. Left alone the clocks and oscillators will be wrong by several seconds a day. The best one will be the real time clock, but even that is going to be pretty poor (they always are). Android is probably doing an NTP updated a couple of times per day, so there will be brief periods in a day when the local clock is close to being accurate (but even then it won't be millisecond accurate).
So even if you do manage to measure time with millisecond precision over months the answers you'll be displaying to the user are going to be wrong by several seconds. You'll be lucky to get within minutes of the actual elapsed time.
If your goal is just to have a stopwatch display rapidly updating when the application is in the foreground, just loop reading the real time clock and calculate/display the time since the stopwatch was started. Don't bother doing anything in the background, just sleep. When your app becomes foreground again resume the loop; the device's real time clock will have been ticking away all the time you're app is asleep, allowing you to calculate and display the time difference. This will be a lot simpler than trying to have a long running background thread, and it will also be more accurate than any other way you might choose (though still not millisecond accurate).

Android external events related stutter

I've been doing several opengl based games for Android recently,
and there's one issue I can't find a way to get rid of.
When system starts some process in background (checking CDMA status, updating an app, or prerry much anything else), the game suffers a whole second stutter. Once in every few minutes. It was an annoying issue, until I started a breakout-style game, which is completely wrecked by that stutter (the ball teleport right through bricks).
It there a way to give the game activity priority over background processes, or pause all those background updates and installs while the game is running?
It there a way to give the game activity priority over background processes
The game activity already has "priority over background processes", to the extent that it can. Generally, background processes run in a class that limits their CPU utilization.
Note that Android's performance in this area has improved over the years. Your symptoms feel like what I would expect from an Android 1.5 device, for example.
or pause all those background updates and installs while the game is running?
No, sorry.

Categories

Resources