Android 优化——电量优化

Android 5.0 后用 Battery Historian 工具分析电量。

耗电因素

  1. 移动网络请求

    手机通过内置的射频模块和基站联系,从而链接上网的,而这个射频模块(radio)是非常耗电的,为了控制这个射频模块的耗电,硬件驱动及 Android RIL 层做了很多处理。例如可以单独关闭 radio(飞行模式),间歇性假休眠 radio(有数据发生时才上电,保持一个频率的与基站交互)等等。如今的 App 都是移动互联网 App,不可避免的会有大量的网络请求,会导致 radio 一直处于活跃状态,从而耗电量增加。

    使用移动网络传输数据,电量的消耗有以下 3 种状态:

    • Full power:高功率状态,移动网络连接被激活,允许设备以最大 的传输速率进行操作。
    • Low power:低功耗状态,对电量的消耗差不多是 Full power 状态下的 50%。
    • Standby:空闲态,没有数据连接需要传输,耗电最少。

    从低功率到高功率大约 1.5s,从空闲态到高功率大约 2s,秒。在应用中每创建一个新的网络连接,网络(射频)模块都会转换到高功率状态(Radio Full Power),在数据传输完后再转回低功耗状态(Radio Low Power),转换的过程需要 5 秒,这 5 秒的耗电量保持在高功率状态,最后再转换空闲态需要 12 秒。因此,对于一个典型的移动网络设备,每个数据传输都会导致网络模块消耗 20 秒的电量。

  2. WakeLock

    Android 系统本身为了优化电量的使用,会在没有操作时进入休眠状态,来节省电量。当然,为了便于开发(很多应用不可避免的希望在灭屏后还能运行一些事儿,或是要保持屏幕一直亮着--比如播放视频),Android 提供了一个 PowerManager.WakeLock 的东西.

    我们可以用 WakeLock 来保持 CPU 运行,或是防止屏幕变暗/关闭,让手机可以在用户不操作时依然可以做一些事儿。然而,获取 WakeLock 很容易,释放不好就会成为难题,消耗电量。例如获取了一个 WakeLock 来保持 CPU 运转,做一个复杂运算并将数据上传到后台服务器,然后释放该 WakeLock。然而这个过程可能并不像我们想象的那么快,可能因为比如服务器挂掉,计算出了异常等等导致 WakeLock 没有释放,CPU 会一直得不到休眠,而大大增加耗电。

    另外,WakeLock 还有 android:keepScreenOn 属性,还可以让屏幕常量,这也是耗电大户。

    private void acquireWakeLock(Context ctx) { if (null == mWakeLock) { PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE, "TestLocknService"); if (null != mWakeLock) { mWakeLock. acquire(); } }
    }
    
    • PARTIAL_WAKE_LOCK:保持 CPU 正常运转,屏幕和键盘灯有可能 会关闭。
    • SCREEN_DIM_WAKE_LOCK:保持 CPU 运转,允许保持屏幕显示,但有可能变暗,允许关闭键盘灯。
    • SCREEN_BRIGHT_WAKE_LOCK:保持 CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯。
    • FULL_WAKE_LOCK:保持 CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度。
    • ACQUIRE_CAUSES_ WAKEUP:强制使屏幕亮起,这种锁主要用于一些必须通知用户的操作。
    • ON_AFTER_RELEASE:当锁被释放时,保持屏幕亮起一段时间。

    需要注册权限

    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.DEVICE_POWER"/>
    
  3. GPS

    应用中经常会用到定位服务,Android 提供了 Network 定位和 GPS 定位。相对来说,GPS 会精确得多,对于一些诸如跑步,导航类的应用基本会使用 GPS 定位。然而,GPS 定位也会消耗大量的电量。

  4. AlarmManager

    间隔不能太短。

优化建议

  1. 优化网络请求

    在蜂窝移动网络下,最好做到批量执行网络请求,尽量避免频繁的间隔网络请求,尽量多地保持在 Radio Standby 状态。

    尽量在 Wi-Fi 环境下使用数据传输。

  2. 谨慎使用 WakeLock

    WakeLock 获取释放成对出现(调用 release),使用超时 WakeLock,以防出异常导致没有释放。

    WakeLock 有一个接口 setReferenceCounted,用来设置 WakeLock 的计数机制,true 为计数,false 为不计数,默认是 true。所谓计数即每一个 acquire 必须对应一个 release;不计数则是无论有多少个 acquire,一个 release 就可以释放。虽然官方说默认 是计数的,但有的第三方 ROM 做了修改,使默认是不计数的。

    主动设置 wakeLock.setReferenceCounted(false)

  3. 监听手机充电状态

    BatteryManager 会发送一个包含充电状态的持续广播,我们可以通过此广播获取充电状态和电量详情。因为这是一个持续广播,无需写 Receiver,可以直接通过 intent 获取相关数据。

    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent batteryStatus = context.registerReceiver(null,ifilter);
    // 设备正在充电
    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS,-1);
    boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||status == BatteryManager.BATTERY_STATUS_FULL;
    // 也可以监听充电状态的变化,只要设备连接或断开电源,BatteryManager 就会广播相应的操作
    int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED,-1);
    boolean usbCharge = chargePlug == BATTERY_PLUGGED_USB;
    boolean acCharge = chargePlug == BATTERY_PLUGGED_AC;
    

    另外页可以注册 Receiver来监听

    <receiver android:name=".PowerConnectionReceiver"><intent-filter><action android:name="android.intent.action.ACTION_POWER_CONNECTED"/><action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/></intent-filter>
    </receiver>
    
  4. Doze and App Standby

    Android 6.0 提供了两个用来节省电量的技术 Doze 和 App Standby。

    • Doze 瞌睡。如果设备闲置了一段较长时间,Doze 技术将通过延迟后台网络活动,CPU 运行等来减少电量损耗。
    • App Standy 应用待机。不是最近得到过用户使用的 App,App Standy 将延缓这个应用的后台网络活动。

    所有 Android 6.0 及以上的设备上,Doze and App Standby 都会运行。可能会影响 App 的运行,可以根据官方文档适配。

    可以在代码中调起电量优化的设计页面,让用户选择是否将应用加入白名单,以在 Doze 模式下能够做一些事情。

  5. 定位

    定位中使用 GPS,及时关闭

    // Remove the listener you previously added
    locationManager.removeUpdates(locationListener);
    
  6. 计算优化

    缩短代码产生指令运行的时间,进而减少某个应用程序对 CPU 时间片 的总占用时间,进而减少单位时间内该应用程序占整个系统耗电的百分比。

    浮点运算比整数运算更消耗 CPU 时间片,因此耗电也会增加,在编写 代码的过程中应该尽量减少浮点运算。

    • 除法变乘法。
    • 充分利用移位。
    • 查表法,直接使用映射关系,但这会增加内存占用,视情况而定。
  7. 熄屏后停止一些和 UI 效果有关的操作,比如动画。

Android 系统性能优化(77)---电量优化相关推荐

  1. Android App优化:内存优化、电量优化、网络优化等 (2)

    -- 优化专题: 整理一系列的专题:比如APK瘦身.插件化.程序架构.性能优化.自定义view.增量升级.移动开发各种技术解决方案等.   Android后期发展的五大趋势:一.性能优化:二.高级UI ...

  2. 【Android 电量优化】电量优化 ( 使用 AlarmManager 保持 CPU 唤醒 )

    文章目录 一.AlarmManager 简介 二.使用 AlarmManager 保持 CPU 唤醒流程 ( 省电操作 ) 三.使用 WeakLock 保持 CPU 唤醒 代码示例 1.Service ...

  3. 【Android 电量优化】电量优化 ( Battery Historian 环境要求 | 电量分析报告 | 电量优化三原则 | 电量优化注意事项 )

    文章目录 一.Battery Historian 环境要求 二.上传电量报告 三.Battery Historian 电量分析报告 四.电量优化三原则 五.电量优化注意事项 参考 Google 官方文 ...

  4. 【Android 电量优化】电量优化 ( 获取电量分析报告 | 阿里云服务器搭建 Battery Historian | 上传并生成分析报告 )

    文章目录 一.Battery Historian 搭建环境 二.获取 Android 手机电量报告 1.重置电量状态 2.开启获取 WeakLock 信息 3.获取手机电量报告 三.阿里云服务器搭建 ...

  5. Android 进阶——性能优化之电量优化全攻略及实战小结(二)

    文章大纲 引言 一.在低电耗模式和应用待机模式下进行测试 1.在低电耗模式下测试您的应用 2.在应用待机模式下测试您的应用 3.列入白名单的可接受用例 4.确定当前充电状态 5.监控充电状态变化 6. ...

  6. 【Android 电量优化】电量优化特性 ( Doze 低电耗模式 | Standby 应用待机模式 | 白名单设置 | 白名单添加系统设置界面 | 指定应用的白名单添加界面 | 测试应用 )

    文章目录 一.Doze 低耗电模式简介 二.Standby 应用待机模式简介 三.Doze 和 Standby 模式测试 四.白名单添加 ( 方式一 ) 五.白名单添加 ( 方式二 ) Android ...

  7. 【Android 电量优化】电量优化 ( 网络状态获取 | 主动获取 WIFI 状态 | 被动获取 WIFI 状态 )

    文章目录 一.获取 WIFI 状态 二.主动获取 WIFI 状态 三.被动获取 WIFI 状态 参考 Google 官方文档 : 优化电池续航时间 一.获取 WIFI 状态 在应用中执行某些操作 , ...

  8. 【Android 电量优化】电量优化 ( 充电状态获取 | 主动获取充电状态 | 广播接受者监听充电状态 | 被动获取充电状态 | 注册空广播接受者获取历史广播 )

    文章目录 一.获取充电状态 二.被动获取充电状态 三.主动获取充电状态 参考 Google 官方文档 : 优化电池续航时间 一.获取充电状态 在应用中执行某些操作 , 如软件云端备份 , 从服务器端获 ...

  9. 【Android 电量优化】电量优化 ( 耗电量测试 | Battery Historian 简介 | apt 源更新 | Docker 安装 | Battery Historian 安装 )

    文章目录 一.耗电量测试 二.Battery Historian 简介 三.Docker 简介 四.更新 apt 源 五.安装 Docker 六.安装 Battery Historian 七.访问电量 ...

  10. 【Android 电量优化】电量优化 ( 唤醒锁定 | 使用 WeakLock 保持服务唤醒 | 屏幕唤醒 )

    文章目录 一.使用 WeakLock 保持 CPU 唤醒 ( 费电操作 ) 1.保持 CPU 唤醒 2.使用 WeakLock 保持 CPU 唤醒流程 3.使用 WeakLock 保持 CPU 唤醒代 ...

最新文章

  1. Tomcat init 脚本并添加服务自启动
  2. model.fit以及model.fit_generator区别及用法
  3. mybatis高级查询
  4. sklearn 神经网络_sklearn中的数据预处理和特征工程
  5. explain 之key rows extra
  6. HTML+CSS+JS实现 ❤️520爱心背景表白网页动画特效❤️
  7. 用python爬虫爬微博_利用python爬取微博热搜
  8. 【算法】159题 Longest Substring with at Most Two Distinct Characters 最大的子串
  9. Rocky4.2下安装金仓v7数据库(KingbaseES)
  10. 设计模式---抽象工厂模式(C++实现)
  11. 陈纪修老师《数学分析》 第06章:不定积分 笔记
  12. LeetCode 55 - 跳跃游戏
  13. IP归属地显示的简单实现代码
  14. 两台计算机和两台交换机的VLAN配置,两台交换机如何配置连接?
  15. 元宇宙专题003 | 如何才能抢先一步,各个省市元宇宙布局抢先看
  16. 不同的count用法
  17. duilib库combo box提供输入字符模糊查询
  18. WPF 绑定继承的样式提示 只能根据带有基类型 IFrameworkInputElement 的目标类型的 Style 样式
  19. 大唐杯学习笔记(1)—— 5G网络架构与组网部署
  20. python爬虫菜鸟教程-Python数据分析,学习路径拆解及资源推荐

热门文章

  1. Linux内核网络协议栈5-socket地址绑定
  2. 2015大学计算机二级考试,2015年计算机二级考试模拟题(一)
  3. webpack3.0 压缩css 但是不在html中引用,webpack怎样压缩css?
  4. mysql 5.6.34 二进制下载_mysql 5.6.34 二进制
  5. ubuntu服务器网站备份,用 Ubuntu 建立 Time Machine 备份服务器
  6. qt mysql分页控件_Qt分页布局与切分窗口的实现
  7. c语言程序设计19,C语言程序设计19.pdf
  8. 【JAVA SE】第一章 Java语言概述、环境变量和HelloWorld
  9. 序列化与反序列化存储、updatepanel
  10. 7.4 流水线的冒险