12.
Android Energy Profiler
Written by Zahidur Rahman Faisal
In the modern day, we can’t live a single moment without our smartphones. Most of the time, we’re either messaging, listening to music, watching videos or snapping pictures with our phones! To serve our needs all day long, smartphones are getting more and more powerful in terms of CPU, battery or storage. Even after having a smartphone with huge battery life, we all see the ‘Low Battery’ alert or run out of battery frequently. This indicates that no matter how powerful your phone is, the apps you use also need to smartly manage energy consumption so you can keep using them as long as you need.
In the previous chapter, you learned to profile network activity and optimize network resource consumption.
In this chapter, you’ll learn to inspect energy consumption with the Energy Profiler that comes with Android Studio.
In the process, you’ll learn about:
- How to use different components of the Energy Profiler tool.
- How to identify resource-hungry events, such as wake locks, jobs and alarms.
- Optimizing energy consumption and monitoring changes.
Overview of The Energy Profiler
The Energy Profiler is a part of Android Profiler tools in Android Studio 3.0 and onwards. The Android Profilers help you investigate different app performance aspects, such as CPU usage, network or radioactivity, GPS & sensor data. The Energy Profiler displays a visualization of how much energy each of these components uses. It also shows you occurrences of system events such as wake locks, alarms, jobs, and location requests, that impact energy consumption.
Energy Profiler appears as a row in the Profiler window once you run your app on a connected device or Android Emulator running Android 8.0 (API 26) or higher.
Follow these steps to open the Energy Profiler:
-
Open the Podplay starter project and run the app on an emulator or connected device using API level 26 or higher.
-
Select View ▸ Tool Windows ▸ Profiler from the menu bar.
-
This will start a new profiling session for PodPlay within the Android Profiler. Click over the ENERGY timeline from the right pane as displayed below:
This will open the actual Energy Profiler, and it’s a detailed representation of the energy consumption from your app in real-time. The new panel will look like this:
As shown above, the Energy Profiler panel includes the following main components:
-
Sessions Pane: Displays your current session info, such as starting time, elapsed time in seconds, and the device name. The sessions pane allows you to start a new profiling session or stop the current session. If you re-launch the app, a new session will be added to this pane with the current timestamp. The session data remains here until you quit Android Studio.
-
Event Timeline: This timeline shows user interactions with the device, such as keyboard inputs, pressing hardware buttons or screen rotation events.
-
Energy Timeline: This shows the estimated energy consumption from your application code. This includes CPU loads, Network activity etc.
-
System Timeline: System events that may affect energy consumption are displayed in this timeline. They could be alarms, scheduled jobs or wake locks. You’ll get to more details about system events shortly.
-
Quick Preview: Using your cursor, hover over any point on the Energy Timeline. It’ll display a quick preview of energy consumption from your app at that point.
-
Timeline Controls: These buttons offer you control over the timelines. The utility of them are as follows:
-
Zoom Out: Zooms out of the timeline, and displays a longer period to allocate more requests, if there are any, in the timeline view.
-
Zoom In: Zooms in on the timeline displaying a shorter period in the timeline view.
-
Reset Zoom: Resets any zoom-out or zoom-in over the timeline view and reverts to the default zoom state.
-
Zoom to Selection: This allows you to zoom into any selected interval from the timeline. This is helpful to focus on a specific time frame that you select to identify a network request which occurred within that period.
-
Attach to Live: This button allows you to pause the timeline at any point or resume displaying the real-time updates jumping to the end of the timeline.
Note: Selection over the timelines in the Energy Profiler is not allowed, so Zoom to Selection will remain disabled.
You might be curious to know more regarding energy management, for example, terms like system events, before putting those components in use!
Android Energy Management 101
Android runtime has a few techniques to ensure your device stays alive and performant for an extensive period. There are system events that consume energy and defense mechanisms that protect the device from unnecessary energy drain. You need to clearly understand these to make your app energy-efficient.
System Events: Wake Locks, Jobs, and Alarms
Energy Profiler logs events that are triggered by the system that can affect energy consumption. These events can be a scheduled background task, a data request using sensors and more.
System events that are displayed in the Energy Profiler fall into the categories below:
-
Wake Locks: There are cases when an app needs to keep the CPU or the screen awake to complete some work. For example, a video-player app might keep the screen on even when there’s no user interaction for a while. A ‘wake lock’ is a system for keeping the CPU and screen on and in use for such cases. Otherwise, the device would go to sleep after a certain time to save energy.
-
Alarms or Background Tasks: Using AlarmManager to schedule background tasks to be executed in the future or at regular intervals is a common approach in Android. However, it’s not the best way to do so. When an alarm’s triggered, it may wake up the device and run energy-consuming operations.
-
Location Requests: Location requests made by GPS consume significant amounts of energy. That’s one of the over-used features in smartphone apps and drains energy quickly.
Doze Mode
From Android 6.0 (API level 23) onwards, Android introduced two power-saving features that extend battery life by managing how apps behave in different conditions. One of them is putting the device on Doze mode when it’s not connected to a power source, in simple words, charging.
Doze mode reduces battery consumption by halting background CPU and network activity when you’re not using a device for an extended amount of time. If a user leaves a device unplugged and stationary for a while, the device enters Doze mode.
Below are the restrictions applied while the device is in Doze mode:
- Suspended network access.
- Ignores wake locks.
- Standard
AlarmManageralarms are deferred. - The system performs no Wi-Fi scans.
- Sync adapters aren’t allowed to run.
-
JobSchedulers are paused.
You must be thinking, how does the system resume these operations then?
Well, the system exits Doze for short intervals to let apps complete their deferred activities. During this time, the system runs all pending syncs, jobs, alarms and so on. This period is the maintenance window.
The diagram below makes it easy to visualize how Doze mode works:
At the end of each maintenance window the system enters Doze again, suspending activities mentioned earlier. The system schedules maintenance windows less frequently over time. This helps to reduce battery consumption in cases of longer-term inactivity when the device isn’t connected to a power source.
As soon as the user uses the device by moving it, turning on the screen, or connecting a charger, the system exits Doze, and all apps return to normal behavior.
Doze mode especially affects AlarmManager alarms and timers-related activities because alarms in Android 5.1 (API level 22) or lower don’t fire when the system is in Doze!
App Standby
App Standby is another energy-saving technique that’s used to prevent unnecessary system events. It’s a state where the system determines if an app is idle or not in use. When in the standby state, apps are deferred from background or network activity.
An app goes to the standby state when the user doesn’t interact with the app for a certain period, and none of the following scenarios occur:
- The user intentionally launches the app.
- The app has any foreground process, either as an activity or service or being used by another activity or foreground service.
- The app receives a notification or generates a local notification.
- The app is an active device admin app, such as a device policy controller. Device admin apps never enter the App Standby state because they must remain available to receive policy from a server at any time.
The system reverts apps from the standby state when the user launches the app again or plugs the device into a power source, allowing them to access the network or execute any pending jobs and syncs. If the device is idle for a long time, the system allows apps on standby to access the network about once a day.
Inspecting and Optimizing Energy Consumption
You must be eager to get your hands on the Energy Profiler and see how you can minimize energy consumption from PodPlay!
Run the app and go straight to the Energy Profiler by clicking the ENERGY timeline.
Observe the Energy and System timeline in this panel — all seems to be normal. Try performing some energy-intensive operations that the app’s supposed to do, for example, playing podcasts, by following these steps:
- Search for the “RW” term and select Return.
- From the channel list, select first. That’ll open the channel details screen:
- Start any podcast by tapping an item. The podcast player will launch. That’s
EpisodePlayerFragment:
Look at your Energy Profiler timeline. Now, you’ll see some anomalies there:
The spikes in the ENERGY timeline indicate some resource-consuming activity. Looking at the highlighted area above, you can be relieved that the CPU and Network usage is still Light, which is a good sign.
But what’s the long, red-colored bar in the SYSTEM timeline? That indicates something needs to be taken care of!
The System timeline displays a color-coded bar for the time range when a system event is active. Different color codes denote the different types of system events:
- Red: Wake locks.
- Yellow: Jobs and alarms.
- Purple: Location events.
If you look carefully at the wake lock, it clearly hints that the wake lock has been called from EpisodePlayerFragment at line 441.
Navigate to that line on EpisodePlayerFragment.kt. You’ll see acquireWakeLock() initiating the wake lock onStart() of the Fragment.
As a media player app, PodPlay may use a wake lock to keep the CPU and screen awake while you’re listening to the podcasts, but it’s also important to release the wake lock as soon as the user leaves the player screen. That’ll save energy consumption and prevent the display from being lit unnecessarily.
To do so, update the onDestroyView() block on EpisodePlayerFragment.kt as follows:
override fun onDestroyView() {
super.onDestroyView()
releaseWakeLock()
_databinding = null
}
That’ll release the wake lock whenever the user quits the player.
Now relaunch the app and play a podcast following the steps above. Then tap the back button until you see the podcast list screen again.
Observe the System timeline for a while. It’ll update like below:
The highlights above confirm the energy event, wake lock, ended shortly after you tapped the back button to navigate away from the player screen. You can extract more info from the displayed logs, such as the process ID (pid), timestamp, and callstack.
Your app is much more energy efficient now, congratulations!
You can play around a bit more or even try to remove the wake lock and see how that impacts the app through the Energy Profiler.
Best Practices for Energy Management
As a developer, you’re in the ultimate control to code your app in a way that allows it to operate with minimal energy and resource consumption. Below are some best practices you can follow while developing your next app:
- Ensure wake locks are released as soon as they are no longer needed.
- If the app is performing any big HTTP downloads, such as media files, consider using DownloadManager.
- If the app needs to synchronize data periodically from a server, use a sync adapter.
- If the app requires background services, consider using WorkManager or JobScheduler instead of AlarmManager.
- Profile early and often to discover energy or performance issues to keep your app up to the mark!
Key Points
- Use the Energy Profiler to monitor, inspect and detect energy-related issues.
- Check out detailed energy stats at any point with the Energy and System events timeline.
- System events are resource-hungry! Be mindful while using them.
- Avoid triggering unnecessary network calls, background tasks or location requests to keep your app energy efficient.
Where to Go From Here?
That ends your adventure of diving as a debugger into the ocean of code and finding the finest solutions!
In this final chapter, you learned how to make the best use of the energy that your smartphone offers you. There’s always more to learn, so continue your quest for energy with these advanced topics: