【Android】APP battery optimization study notes

Reasons for power optimization

Battery optimization is very important in Android development for the following reasons:

user experience:

Battery life is one of the factors that users pay great attention to when using mobile devices. By performing power optimization, the battery life of the device can be extended, allowing users to use the device for a longer period of time without having to recharge frequently. This will greatly improve user satisfaction and overall experience.

Equipment performance:

The battery life of a mobile device is directly related to the performance of the device. It provides better performance and responsiveness when the device's battery is fully charged. However, when the battery power is low, in order to extend the battery life, the system may reduce the performance of the device, which will affect the operating efficiency of the application and the user experience. By performing power optimization, system adjustments to device performance can be minimized to ensure that applications can provide good performance in various power states.

resource utilization:

The battery is one of the important resources of a mobile device, and it is limited. By performing power optimization, battery resources can be reasonably managed and utilized to prevent applications from consuming too much power in the background, thereby reducing unnecessary waste of power. This is of great significance for the long-term use of equipment and environmental protection.

requirements:

The update of the Android system version usually introduces new battery optimization rules and restrictions, requiring application developers to abide by them. For example, Android 6.0 (Marshmallow) introduced Doze Mode and App Standby, features that reduce power consumption by limiting app activity in the background. In order to ensure that the application runs normally and meets the specifications on the new version of the system, power optimization is necessary.

Doze low power consumption mode and StandBy standby mode

When the user has not used the device for a long time, 低电耗模式会延迟应用的后台 CPU 和网络活动,从 而降低耗电量。应用待机模式会延迟用户近期未与之交互的应用的后台网络活动.

Doze Low Power Mode

If the device 未充电、屏幕熄灭、让设备在一段时间内保持不活动状态, then the device will enter Doze mode. In Doze mode, the system will try 限制应用访问占用大量网络和 CPU 资源的服务to save power by. It will 阻止应用访问网络, and will 延迟其作业、同步和标准闹钟.

Doze is a nap in Chinese, so 系统会定期退出nap for a short period of time to let the application complete its delayed activities. During this maintenance period, the system runs all pending syncs, jobs, and alarms, and allows applications to access the network.

Once the user wakes the device by moving the device, turning on the screen, or connecting to a charger, the system will 立即退出低电耗模式and all apps resume normal activity.

While in Doze, apps are subject to the following restrictions:

1.暂停访问网络

2. The system ignores PowerManager.WakeLockwake locks.

3. Standard AlarmManager 闹钟(including setExact() and setWindow()) 推迟到下一个维护期.
If you need to set an alarm clock that is triggered when the device is in low power consumption mode, please use API 23 (6.0) setAndAllowWhileIdle() (one-time alarm clock, same as set method) or setExactAndAllowWhileIdle() (higher precision
than , same as setExact ).
Alarms set with use setAlarmClock() will continue to fire normally, and the system will exit Doze shortly before those alarms fire
.

4. System 不执行 WLAN 扫描.

5. System 不允许运行同步适配器AbstractThreadedSyncAdapter (account sync pull live).

6. System 不允许运行 JobScheduler.

Standby standby mode

App standby mode 允许系统判定应用在用户未主动使用它时是否处于待机状态. When the user does not touch the application for a period of time and the application does not have the following performance, the Android system will make the application enter the idle state

1. 应用当前有一个进程在前台运行(as an activity or foreground service, or is being used by another activity or foreground service).

2.应用生成用户可在锁定屏幕或通知栏中看到的通知

When the user plugs the device into a power source, the system releases apps from standby, allowing them to freely access the network and perform any pending jobs and syncs.

If the device is idle for an extended period of time, the system will allow idle apps to access the network approximately once a day.

whitelist

The system provides a configurable whitelist of apps that are partially exempt from Doze and App Standby optimizations. Whitelisted apps can use the network and retain partial wake locks during Doze and App Standby. However, whitelisted apps will still be subject to other restrictions, just like other apps. For example, jobs and syncs for whitelisted apps are delayed (on devices 6.0 and below), and their regular AlarmManager alarms don't fire. An app can call PowerManager.isIgnoringBatteryOptimizations()to check if the app is currently on the exemption whitelist.

The whitelist can be manually configured in Battery Optimization in Settings. Additionally, the system provides methods for apps to ask the user to whitelist

Apps can fire ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGSIntents that take users directly to Battery Optimization, where they add the app.

startActivity(new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));

Apps with the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission can trigger a system dialog to let the user add the app to the whitelist directly without going to Settings. Such applications will ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
trigger the dialog by firing an Intent.

Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:"+getPackageName()));
startActivity(intent);

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Test in Doze
#启用Doze
adb shell dumpsys deviceidle enable

#强制进入doze模式 (同时还需要关闭屏幕)
adb shell dumpsys deviceidle force-idle

#退出doze模式
adb shell dumpsys deviceidle unforce

#关闭doze
adb shell dumpsys deviceidle disable

#重置设备
adb shell dumpsys battery reset

#查看doze白名单
adb shell dumpsys deviceidle wh
Test in App Standby
#设置断开充电
adb shell dumpsys battery unplug

#进入standby
adb shell am set-inactive <packageName> true

#退出standby
adb shell am set-inactive <packageName> false

#查看是否处于standby
adb shell am get-inactive <packageName>

#重置
adb shell dumpsys battery reset

Monitor battery level and charging status

Get charging status
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = registerReceiver(null, ifilter);

// 是否正在充电
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;

// 什么方式充电?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

//usb
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;

//充电器
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
Log.e(TAG, "isCharging: " + isCharging + " usbCharge: " + usbCharge + " acCharge:" + acCharge);
Monitor Charge State Changes
//注册广播
IntentFilter ifilter = new IntentFilter();
//充电状态
ifilter.addAction(Intent.ACTION_POWER_CONNECTED);
ifilter.addAction(Intent.ACTION_POWER_DISCONNECTED);

//电量显著变化
ifilter.addAction(Intent.ACTION_BATTERY_LOW); //电量不足
ifilter.addAction(Intent.ACTION_BATTERY_OKAY); //电量从低变回高

powerConnectionReceiver = new PowerConnectionReceiver();
registerReceiver(powerConnectionReceiver, ifilter);

public class PowerConnectionReceiver extends BroadcastReceiver {
    
    
  @Override
  public void onReceive(Context context, Intent intent) {
    
    
    if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
    
    
        Toast.makeText(context, "充电状态:CONNECTED", Toast.LENGTH_SHORT).show();
    } else if (intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
    
    
        Toast.makeText(context, "充电状态:DISCONNECTED", Toast.LENGTH_SHORT).show();
    } else if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW)) {
    
    
        Toast.makeText(context, "电量过低", Toast.LENGTH_SHORT).show();
    } else if (intent.getAction().equals(Intent.ACTION_BATTERY_OKAY)) {
    
    
        Toast.makeText(context, "电量从低变回高", Toast.LENGTH_SHORT).show();
    }
  }
}
Energy Profiler

On Android 8.0+ devices, use the Energy Profiler to see where apps are using unnecessary power. EnergyProfiler monitors CPU, network radio, and GPS sensor usage and provides a visual display of how much power each of these components is consuming. Also shows the number of occurrences of system events (wake locks, alarms, jobs, and location requests) that may affect power consumption.

Guess you like

Origin blog.csdn.net/qq_43358469/article/details/132027679