文章目录
- iOS应用能源效率指南
- 一、能源要点
- 二、减少工作并按优先顺序排列
- 1、减少后台工作
- 2、准确指定`QoS`优先级
- 3、减少计时器的使用
- 4、最小话 I/O
- 5、对`低电量模式`做出响应
- 三、最小化和延迟 `网络请求`
- 1、最小化网络请求
- 2、推迟网络请求
- 3、VoIP最佳做法
- 四、有效使用图形、动画、视频
- 五、优化位置和动作
- 1、降低位置的准确性和持续时间
- 2、减少运动更新的频率
- 六、优化通知
- 七、蓝牙最佳实现
- 八、Watch最佳做法
- 九、监控能源使用
- 1、观察能源泄露的迹象
- 2、使用Xcode衡量能源影响
- 3、用`Insruments`测量能量影响
iOS应用能源效率指南
一、能源要点
耗电量、速度、交互迅速、温度
二、减少工作并按优先顺序排列
1、减少后台工作
避免以下行为:
- 后台活动完成后不通知系统
- 播放无声音频
- 执行位置更新
- 与蓝牙配件互动
- 可以推迟的下载
applicationWillResignActive
将要进入非活跃状态
applicationDidEnterBackground
将要进入后台,几秒种
如需更多时间:
代码语言:javascript复制let bgTaskID: UIBackgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler() {
// 处理比较耗时操作
}
// 其他初始化
// 告知系统后台任务已完成
UIApplication.sharedApplication().endBackgroundTask(bgTaskID)
2、准确指定QoS
优先级
可以设置 线程、队列、任务 的优先级
NSOperation | GCD | |
---|---|---|
User-Interactive | Main thread | 用户交互:刷新页面、动画… |
User-Initiated | High | 用户启动:打开/保存文档、点击… |
Default | Default | GCD全局队列 |
Utilize | Low | 不需要立即得到结果的, 通常有进度条:下载、导入… |
Background | Background | 后台运行,用户不可见:同步、备份 |
3、减少计时器的使用
利用GCD
的group
、queue
、semaphore
、等 比计时器更有效。
必须使用计时器时:
- 指定适当的超时时间
- 不再需要时Invalidate掉
- 设置计时器触发时差tolerances
4、最小话 I/O
- 最小化数据写入
- 避免过于频繁的访问内存
- 尽可能顺序的读取和写入
- 从文件中读取和写入更大的数据块?
- 读取和写入大量数据时,考虑使用
dispatch_io
优化文件访问 - 如果数据由随机访问结构组成,建议存在数据库中,用
SQLite
orCore Data
访问 - 了解系统如何缓存文件,并了解如何优化这些缓存的使用。除非打算多次引用数据,否则避免自己缓存数据
5、对低电量模式
做出响应
减少动画使用、降低帧频、停止位置更新、禁用同步和备份等
观察电量模式通知: NSProcessInfoPowerStateDidChangeNotification
三、最小化和延迟 网络请求
1、最小化网络请求
- 降低媒体质量和尺寸
- 压缩资料
- 避免多余的传输:缓存数据、使用可暂停可恢复的传输
- 检查网络状态:网络不可用时,勿执行请求
- 提供取消操作
- 网络可用时,可尝试重试
2、推迟网络请求
- 批量传输:而不是等待用户点击后再多次请求
- 酌情创建可延迟的网络请求:
NSURLSession
提供了background Session功能:
let config = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.<YourApp>.<YourBackgroundSessionIdentifier>")
config.discretionary = true // 由系统酌情决定什么时候执行
config.allowsCellularAccess = false // 仅Wi-Fi时执行
let bkgSession = NSURLSession(configuration: config, delegate: self, delegateQueue: nil) // 创建后台Session
let downloadUrl = NSURL.URLWithString(<YourURLString>)
let downloadRequest = NSURLRequest.requestWithURL(downloadUrl)
let downloadTask = bkgSession.downloadTaskWithRequest(downloadRequest)
downloadTask.resume()
func URLSession(session: NSURLSession, downloadTask downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
// 下载完成
}
3、VoIP最佳做法
使用VoIP推送来避免持久连接(iOS8开始支持PushKit VoIP)
四、有效使用图形、动画、视频
- 减少视图数量
- 减少透明度的使用
- 清除不可见的视图,如:移除屏幕的、被遮挡的、等等
- 尽可能使用较低的动画帧率
- 在动画的声明周期请保持一致的帧率
- 避免在屏幕上使用多个帧率,哪怕需要提高低帧率的那个
- 开发游戏时使用推荐框架:SpriteKit、Metal
- 播放全屏视频时,限制UI层级的使用(自动隐藏,点击再显示)
五、优化位置和动作
1、降低位置的准确性和持续时间
- 请求快速位置更新:
requestLocation()
- 不使用时停止定位服务:
stopUpdatingLocation()
- 降低定位准确性:
desiredAccuracy
- iOS默认:
kCLLocationAccuracyBest
最好 orkCLLocationAccuracyNearestTenMeters
十米。 - 通常提供的会比要求的准确:如
kCLLocationAccuracyThreeKilometers
时,一百米左右精度
- 后台定位时:
- 设置
pausesLocationUpdatesAutomatically
有助于省电 - 设置
activityType
指定活动类型,有助于系统判断什么时候通知您 - 设置可延迟的位置和时间更新:
.allowDeferredLocationUpdatesUntilTraveled(distance, timeout:time)
- 将位置更新设置位特定区域or位置:进入 某一区域、iBeacon范围
- 访问监控
Monitoring
:
self.locationManager.startMonitoringVisits()
func locationManager(manager: CLLocationManager, didVisit visit: CLVisit!) {
// 经常访问的位置
self.locationManager.stopMonitoringVisits()
}
- 不到万不得别使用
Significant-Change
更新
非常耗电,并且需要获取额外权限kCLAuthorizationStatusAuthorizedAlways
。照理上面的区域和访问监控已足够一般App使用。
self.locationManager.startMonitoringSignificantLocationChanges()
func locationManager(manager: CLLocationManager, didFinishDeferredUpdatesWithError error: NSError!) {
// Perform location-based activity
self.locationManager.stopMonitoringSignificantLocationChanges()
}
2、减少运动更新的频率
如:加速度计、陀螺仪、磁力计。
- 不再需要时停止方向更改通知,如:
DidLoad
时开始、DidDisappear
时结束 - 要求更少的连续运动更新:
CMMotionManager
设置Interval
详情见文档
六、优化通知
- 尽可能使用本地通知
- 服务器推送支持两种优先级:立即发送、延迟发送
七、蓝牙最佳实现
- 仅在需要时扫描设备
- 减少重复设备发现的处理:避免将
scan
方法的参数options
设置为CBCentralManagerScanOptionAllowDuplicatesKey
- 仅
discover
需要的services
和characters
:discover时指定UUID - 订阅修改通知,而不是轮询特征值的更改:
setNotifiyValue:forCharacteristic:
- 不在需要设备时断开连接:
cancelPeripheralConnection:
八、Watch最佳做法
- 减少watch和iPhone之间的交互:使用Watch Connectivity框架来优化数据传输
- 减少网络请求次数
- 优化图形和媒体
- 清除不必要的内容更新
- 使用较深的颜色
- 保持较小的介质尺寸
- 减少工作量:如有需要,考虑交给iPhone处理
九、监控能源使用
1、观察能源泄露的迹象
- 电池量耗尽
- app应该空闲时的活动
- 用户界面反应迟钝or缓慢
- 主线程上的大量工作
- 大量使用动画
- 大量使视图的透明
- 交换
- 内存停滞和缓存未命中
- 内存警告
- 锁争用
- 上下文切换过多
- 过多使用计时器
- 屏幕上绘制过多
- 磁盘I/O过多or重复
- 高开销通信,如:带有小数据包和缓冲区的网络活动
- 防止设备睡眠
2、使用Xcode衡量能源影响
- 调试仪表:Xcode的导航栏上选择View->Navigators->Show Debug Navigator
- Energy impact 图表:(能量冲击计)
- 条形图:蓝色是app本身执行工作所消耗的能量;红色是额外使用的系统资源,需要加电才能执行的工作
- 灰色正方形:CPU、GPU、Network、Location、Background后台活动
- CPU压力表:当app被认为有低CPU活动or app是空闲的时发生的峰值可能表明可以进行优化
- Disk磁盘使用量规:磁盘读取和写入活动,app已打开的文件。可识别意外or重复的I/O活动
- Network:记录所有入站和出站的网络流量。找到可延迟的活动进行优化
3、用Insruments
测量能量影响
- 使用
Energy Diagnostics
收集诊断模板
直接再iOS上记录能源使用情况:Developer -> Logging -> start Recording -> 操作你的app -> stop Recording,打开Energy Diagnostics
选择 File -> Import Logged Data form Device 进行分析。
- Activity Monitor:总体CPU、磁盘I/O、网络使用情况
- Core Animation:图形性能、CPU使用率。
- Time Profiler:线程执行时间
- Blank:自定义模板
Energy Efficiency Guide for iOS Apps