电量优化

电量优化

重视程度不够、电量消耗线上难以量化

电量消耗监控方案

  • 系统设置–耗电排行

    • 直观,但没有详细数据,对解决问题没有什么帮助
  • 监听电量消耗广播:ACTION_BATTERY_CHANGED

    • 获取电池电量、充电状态、电池状态等信息,价值不大,针对手机整体的耗电量,非特定App

      1
      2
      3
      4
      IntentFilter filter = new IntentFilter();
      filter.addAction(Intent.ACTION_BATTERY_CHANGED);
      Intent intent = registerReceiver(null, filter);
      LogUtils.i("battery " + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1));
  • Battery Historian【推荐】

    • Google 推出的一款 Android 系统电量分析工具,可视化展示各项耗电指标

    • 适合线下使用

    • 使用方式

      • 安装:参考 github 地址或使用三方网站:https://bathist.ef.lc/

      • 使用:

        1
        2
        3
        adb shell dumpsys batterystats --reset # 电量重置
        adb shell dumpsys batterystats --enable full-wake-history # 开始统计耗电信息
        adb bugreport bugreport.zip # 导出电量信息
      • 上传分析

电量辅助监控

获取系统组件耗电情况

Android 系统中,手机的每个组件:cpugps、显示屏、wifi、蓝牙等等,运行时的能耗都保存在一个名为 power_profile 文件中
可以通过命令

1
adb pull /system/framework/framework-res.apk

反编译找到 power_profile 文件,来获取各个组件的能耗值

【注意】线上是无法获取该文件的,可以在线下辅助使用,通过查看手机那个模块耗电量比较严重,然后查看项目中那里调用了该模块,然后进行特点调优

获取耗电组件的调用次数和执行时间
  • 通过 Aop 的方式进行监控:可以在关键性方法中通过 AOP 的形式进行监控调用堆栈和执行时长

  • 线程使用时长超过阈值预警:以防止线程在长时间处理循环函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // lancet aop
    public static long runTime = 0;
    @Insert(value = "run")
    @TargetClass(value = "java.lang.Runnable",scope = Scope.ALL)
    public void run(){
    runTime = System.currentTimeMillis();
    Origin.callVoid();
    LogUtils.i("runTime "+(System.currentTimeMillis() - runTime));
    }

电量优化总结

  • CPU 时间片

    • 通过 CPU ProfilerTraceView 定位 CPU 占有率异常
    • 减少后台应用的主动运行
  • 网络相关

    • 要控制好网络请求时间和次数
    • 数据压缩,减少请求时间
    • 非必要禁止使用轮询的方式进行业务操作
  • 定位相关

    • 根据场景谨慎选择定位模式
    • 考虑网络定位代替GPS
    • 使用后要及时关闭,减少更新频率
  • 界面相关

    • 动画和网络请求等在界面不可见时需要停止相关的活动
    • 耗电操作判断前后台
  • WakeLock相关

    • 一定要成对出现:acquirerelease,确保一定会被释放
    • 可以考虑使用带参数的 acquire
    • 屏幕常亮场景可以考虑使用 keepScreenOn 即可
  • JobScheduler

    • 在符合某些条件时创建执行在后台的任务
    • 把不紧急的任务放到更合适的时机批量处理