Hey, I finished my code and everything works as it should but I'm wondering since smartphones have limited battery, CPU .. How can I check if my application will run good on older phones? and how can I check if my app consumes the phones battery?
Thanks
The only way to really know it to test the app in the phones.
That said, you can profile it and make educated guesses based on how CPU-intensive is your app, for how long is it running, if you have services using cpu continuously, etc.
There are a few things to consider:
The main battery drain is the screen. If you keep any kind of screen lock (even dim), it will destroy the battery.
Any other lock (wifi, etc.), will induce battery drain. Do you use them? Do you need them? Do you release them as soon as they're not needed?
Do you have hardware listeners (e.g., location, accelerometer), unregister them as soon as they're not needed
Take a look at this video: http://www.google.com/events/io/2009/sessions/CodingLifeBatteryLife.html
Also take a look on
http://developer.android.com/guide/developing/debugging/debugging-tracing.html
Related
There is an application that every day creates about 100-200 new wakelocks for android. each wakelock is used once and after using it is no longer needed, but remains in the system. Thus there are a lot of unused wakelocks in the system. How do you think this is correct? or is it bad for system performance?
if you are wondering what kind of application it is and how this is possible, then see the link:
https://github.com/iNPUTmice/Conversations/issues/4012
Is it bad for system performance?
In terms of compute, probably no real effect since the app completes its work and yields. Especially if the app is in foreground during this time, and the work is relatively quick (roughly <1 min or so)
In terms of battery use, questionable. If its the highest wakelock level (screen + CPU), when the user turns off the screen, they are released. If its just the CPU wakelock, then they'll hang around and keep draining battery. Though later android versions and OEM optimizations may just remove wake locks after some time.
Is it bad practice? YES!
This undoubtedly drain power more than it should and gives the system the impression the app needs to keep either the CPU running for longer than required influencing OS incorrectly.
Also note that this is a generic question rather than a specific issue, so you may get a better answer from https://softwareengineering.stackexchange.com/
So, I've a Service that is important for applications logic and thus needs to be alive all the time.
First thing is first, I created it as a foreground service.
Whenever user starts to run, Service starts to do a lot of heavy things. It uses FusedLocationAPI different type of sensors and do a lot of different calculations. At this point phone starts to heat up (CPU usage is high). When running stops, heating stops and CPU drops lower.
This makes me think that the main problem is whenever these sensors are used and calculations are made, but there's a lot of possibilities that could cause this and I wanted to understand, how can I deeply analyze batter usage in this case? I read that Battery Historian should be way to go, but the information there is complicated and do not give me much information. How can I use this data to understand which class/runnable/code part is held responsible for the CPU usage? Maybe there's better ways to solve this? Thanks in advance.
Detailed analysis on what's happening using CPU profiler (after suggestion).
Image. Application is opened and few different screens are switch to and from. Nothing special. Phone does not heat up and from CPU analysis everything also looks pretty okay.
2.User starts to run and enter heavy state. The yellow (light green) rectangle shows previously mentioned "important service" that bring important role to application. Called functions does not use too much time of CPU considering the % of whole running trip - which makes me think, I've to look somewhere else..
What I saw is that CPU increases heavily whenever I lock the phone (while service is running. From CPU Bottom Up analysis I cannot understand what is causing the problem (orange rectangle) - looks like a bunch of Android stuff is happening, but it does not give me any clue.
From CPU profiler I do understand that I have a serious problem considering CPU usage, but right now I do not understand what is causing it (which piece of code/class/function). I know for the fact that whenever my important service is created (on app start) I use PARTIAL_WAKE_LOCK to not allow CPU go to sleep and also make service to be alive at all times. As I understand I need to find different solution for this, because CPU drains too much of battery.
How could I found this using only profiler? I now this fact only for code and profiler stack does not tell me much about this (maybe Im not looking at the right place?)
I found out the root cause of high CPU usage.
I did detailed investigation on threads and found out that DefaultDispatcher threads are using A LOT of CPU.
Turns out the has been a bug in Kotlin-Coroutines library and latest version provides fixes. When I did tests I used version 1.3.1, but changing version number to 1.3.3 provided me with big improvements: from 40% usage to 10% CPU usage.
It is a well known issue that many Android phones switch off the accelerometer when the screen goes off. However something seems to have changed with Android Fit (the app). Fit keeps counting steps even when the screen goes off. If Fit is installed, then events are raised for step counting within the Fit environment and I am able to capture them using
Fitness.SensorsApi.findDataSources(mClient, new DataSourcesRequest.Builder()
.setDataTypes(DataType.TYPE_STEP_COUNT_CUMULATIVE)
I have tested this on a Samsung S4 and on a Oneplus One and in both cases the steps are counted.
How do they do that? What Android classes do they use?
My understanding is that the available method introduced since Kitkat is to implement a SensorEventListener. For example theelfismike provides code that implements this. However on many phones the step counting stops when the screen goes off. Interestingly the counting does not seem to stop if the Google Fit app is installed (hence I guess they keep the accelerometer on).
Am I missing something? Is the functionality of keeping counting steps after screen off available to the mortal programmers?
Thanks!
As Ilja said, your code runs even after the screen gets turned off. But in this case I guess we need a little different answer.
They definitely use a Service that keeps a wakelock and they query the sensors for data. Important part here is holding the wakelock - you have to prevent the device from going into sleep during lifetime of your service - if you don't want to miss some data.
But this approach will be drain the battery really fast, because in order to detect steps you need to process quite a lot of data from sensors.
Thats why there is sensor batching. That allows you to get continuous sensor data even without keeping the device awake. It basically stores the sensor events in a hw based queue right in the chip itself and only sends them to your app (service,..) at predefined intervals in batches. This allows you to do a 24/7 monitoring without draining the battery significantly. Please note that only supported chipsets can do that (you can find details in Android docs), in case of older phones you need to fallback to the hideous wakelock keeping method in order to get your data.
You can also just use Google Fit APIs, but this would only work when there're both Google Fit + Google Play Services installed on the device with monitoring turned on.
Every normal Thread is keep on working when the screen goes off or when the Activity lost its focus...but when the activity gets killed then all thread are killed...
However you can use services for longrunning tasks like asking the accelerometer for example
I want to monitor battery usage on a very granular level. Like what is the battery usage of each individual activity, or even more granular detail like what is the battery usage in running a for loop of my app. Is there any android app or developer tool using which I can do that on an app whose code I already have?
No, because your phone is not capable of measuring "battery usage on a very granular level".
The closest you will get is with a Qualcomm MDP device and their battery measurement software. Even then, the battery usage by process is somewhat guesswork, as the contributors to power drain (CPU, screen, radios, etc.) are shared by all running processes that use them. A few other off-the-shelf devices may also work as well, though I suspect that the battery measurement software will work a lot better on an MDP, as it has dedicated hardware for this stuff.
Getting finer-grained detail than that will be impractical. At best, with a lot of testing, you might be able to draw some conclusions comparing two algorithms, but for most such algorithms, you would probably be just as well off measuring how much CPU time they took, and extrapolate battery usage from there.
I'm guessing that you want to use algorithms that are very efficient to minimize power usage by your program. If this is true, you are going about it the wrong way. The power consumption by computational algorithms is trivial compared to (a) the usage of external peripherals such as blue tooth and wireless, and (b) preventing the processor from dropping into an idle state. To maximize the power efficiency of your app, you want it to be idle (meaning asleep, not spinning) for as long as possible.
I'm currently developing with Android SDK, and because I'm building an application based on camera, I cannot use the emulator to test it.
This means that the following scenario happens quite frequently
I connect my phone to USB the battery is 50%
I disconnect it before it is fully charged, e.g. 80%
I have to leave, and I want to take my phone with me
I come back and connect again and so on...
I read that Lithium-ion batteries don't suffer the memory effect, but, on the other hand, I also read that one should wait until the battery is fully charged before disconnecting it from the USB.
So, I'm wondering if the way I'm using the phone now for debugging may damage or reduce the life of my battery
Any advice is appreciated
First of all, I'm not an expert in this subject.
Lithium-ion battery, as you say, does not suffer the charge memory effect but they have the "digital memory" (affects the accuracy % remaining battery) as reflected in this article (so you have to fully-discharge - fully-charge periodically the battery to avoid this):
Source: http://www.techrepublic.com/blog/five-tips/five-tips-for-extending-lithium-ion-battery-life/289
More info about it:
"Partial discharge on Li-ion is fine; there is no memory and the battery does not need periodic full discharge cycles other than to calibrate the fuel gauge on a smart battery"
So partial discharge is not a problem. The worst condition is keeping a fully charged battery at elevated temperatures
Source: http://batteryuniversity.com/learn/article/how_to_prolong_lithium_based_batteries
About the need to fully-charge in Lithium-ion batteries, I did find a source about it, but in Apple support you can find this:
"You can disconnect and use your iPod before the battery is fully charged. You don't have to wait until the battery is completely empty before charging it again. This is because lithium-ion batteries, such as those used in iPod, have none of the memory effects seen in nickel-based rechargeable batteries"
Source: http://support.apple.com/kb/ht1384
Conclusion: Your partial charges/discharges won't be noticeable. If you want to extend the battery life, follow the suggestions you can find in the first two articles (avoid hot, don't let fully discharge... etc).