Profiling Android apps for battery consumption



    I think that sooner or later, every Android user needs to understand which application consumed the entire battery overnight, even though the phone was off the screen. The fate of the culprit found is not enviable: most often it is simply deleted. So, what can be done so that our applications use the battery minimally? In the article, I will try to answer this question and talk about approaches to reducing battery consumption that I have used.



    Quantification


    First of all, let's agree on how we will measure battery consumption in order to monitor progress after some corrections in the code. All that is available to us is the percentage of battery power. We will focus on it. This value varies depending on so many factors.

    To reduce the measurement error, it is advisable:
    • use the same device;
    • use the same part of the scale (the fact is that a change in one percent of the charge on different parts of the scale means a change in a different charge, for example, from 100% to 99% usually discharges faster than from 90% to 89%);
    • Before starting a series of battery tests on the device, it is advisable to do a factory reset;
    • reboot the device before each test;
    • during one test, discharge the device by more than 10% so that the measurement error is not very large;
    • Do not install or launch any new applications during a series of tests; they can consume a battery in the background;
    • Do not change device settings: screen brightness, network settings, etc .;
    • Do not move the device over significant distances (more than several meters) during the test or during each test move it along the same path.

    What does the battery do?


    The main consumers of the battery are:
    • CPU operation
    • screen backlight;
    • GPU operation
    • work with a network;
    • Frequent GPS acquisition.

    I think this list is familiar to many Android developers. Most interesting, what is the contribution of each of these points. Of course, it can be different. And here are my observations.
    • The CPU is often the main consumer;
    • the backlight often takes no less than a CPU;
      It is very important not to change the brightness of the backlight during comparative tests. Otherwise, it may distort the result. For example, when I measured how the change in brightness affects the battery consumption on the Nexus 5, which lasted more than a year, I got the following result: changing the screen brightness from 20% to 80% increased the battery consumption by 15% per hour.
    • consumption for network operation can increase significantly if the phone is moving and if the cellular signal is poor;
      This is due to the cost of finding cellular points. As with the brightness of the screen, keep in mind that this can affect the test results.
    • The effect of consumption on obtaining GPS coordinates is often enhanced by the fact that when the coordinate is updated, a callback is called, in which a certain amount of code is executed.

    What can we influence to reduce battery consumption by the application? Not really much.
    • First of all, it reduces the load on the CPU. This is the main way to reduce battery consumption. It makes sense to profile the application to use the CPU. If possible, transfer part of the load to the GPU. This can make a significant contribution.
    • Then the network. It makes sense to buffer data so that it is less likely to access the network. It details how to reduce battery consumption when transferring data over a network.
    • Next is GPS. If an exact, frequently updated coordinate is not required, do not request it. It is worth considering the possibility of determining the coordinates via WiFi. It is well written about this.


    Battery Consumption Profiling


    We will need:
    • An Android device with OS 5.x and a fairly new battery. If possible, he should do a factory reset.
    • Profiler: github.com/google/battery-historian . It needs to be installed on the desktop and tested before tests.

    Each experiment consists of the following steps:
    1. Fully charge the battery. It is important that later it is possible to compare the results of experiments with each other on the same part of the battery scale.
    2. Install the application under test on the device.
    3. Reboot the device. This is necessary because otherwise, other applications running in the background may affect the result.
    4. Reset battery statistics: adb shell dumpsys batterystats --reset
    5. You can also enable statistics on wakelock. By default, it is off: adb shell dumpsys batterystats --enable full-wake-history
    6. Do not forget to disconnect the device from the computer so that it does not charge.
    7. Then, run the tested application.
    8. And put off the device for several hours, so that it is discharged by at least 10-15%. During the test, it is advisable not to touch the device and not turn on the screen, as this may affect the result.
    9. We study the data during the test.

    The last step will dwell in detail. There are two ways to study the test data. You can use the profiler developed by Google. And you can use the UI in the Android settings.

    1. Battery-historian profiler
    First of all, the profiler shows different UIs for Android 5.x and for earlier versions of the OS. Moreover, the quantity, completeness of data and ease of display differ markedly in favor of Android 5. On the other hand, the results of profiling an application on a battery can differ markedly if you run it on different versions of Android. I recommend starting profiling with Android 5, and then be sure to repeat the process on earlier versions of the OS.

    2. UI in Android settings
    Everything is simple here. On the phone, go to Settings -> Battery. Percentage means how much percent of the battery is spent on each application. For 100%, everything that was spent during the test is taken.



    For example, the screen above shows that statistics were collected from around 10 p.m. to 7:30 a.m. During this time, the device is discharged by 72% (100% - 28%). 14% of what was discharged (i.e., from 72%) went to the screen. 12% on MAPS.ME. If you click on an item in this list, you can get detailed information about the expense for the selected application. This screen also shows that consumption has risen sharply from 6 to 7 hours. It often happens that an application actively uses Google Apps, and the charge is charged to them. This is also seen in the screenshot above. This dialog allows you to quickly understand what is happening with the application against the background of other applications and services launched by the system. And in the case of Android 4.x and earlier, it gives data that cannot be obtained using the profiler.

    Working with the battery-historian profiler


    First, the profiler must be installed. The installation process is described in detail here . It includes:
    • go installation: golang.org/doc/install
      If you install go, as suggested by default, in the $ HOME / go directory, then just set the following environment variables after installation:
      export GOPATH = $ HOME / go
      export GOBIN = $ GOPATH / bin
    • protobuf installation;
    • installing a battery-historian profiler.

    Next, we connect the device and collect information about the battery consumption since the last charge data reset (it happens if the battery is fully charged or if the command was called: adb shell dumpsys batterystats --reset):

    adb bugreport > bugreport.txt
    

    Run the profiler:

    cd $GOPATH/src/github.com/google/battery-historian
    go run cmd/battery-historian/battery-historian.go
    

    We go in the browser at the address:
    http: // localhost: 9999

    In the window that opens, select the previously saved bugreport.txt file.

    The results that you see in the browser will depend on the version of Android from which bugreport.txt was downloaded. For Android 5.x, a page with a series of tabs and a wide variety of information is displayed, including statistics for each application in the system. General statistics of battery consumption on the device:





    Application statistics:



    For Android 4.x we get this dialog. It is significantly less informative, but you can understand from it what is happening with consumption in general.



    Application Profiling Modes


    It makes sense to check in at least two modes:
    • foreground application;
    • application in the background.

    It is desirable that the application in the background does not consume resources at all, if there are no very good reasons for that. In addition, it is often worth checking separately how the application consumes battery while driving. Especially if it uses GPS or is otherwise connected with the location.

    Battery degradation


    It is important to consider that over time, the battery charge weakens. I had a case when for half a year the application began to discharge the battery one and a half times faster. The reason is battery aging. This should be considered when testing. If the application ate the entire battery of the device in 4 hours of operation six months ago, then most likely it will now eat the battery in less time. And the reason is not that something has gone wrong in the application.

    Comparison with competitors


    I want to note that the above methods do not require access to the source code of the application. This means that you can compare how your application consumes battery compared to competitors.

    Conclusion


    In this article, I described the approaches to reducing battery consumption that we take when working on MAPS.ME at Mail.Ru Group. It would be interesting to hear if someone uses some other means and technologies to solve the same problem. Write in the comments.

    Also popular now: