iOS性能优化(三)能耗

如今的移动设备早已无处不在,待机时间成为影响设备最终销量的一个重要因素。类似地,电量消耗也是决定某个应用是否会被安装的重要因素之一。
设备中的每个硬件模块都会消耗电量。电量的最大消费者是CPU,但这只是系统的一个方面。一个编写良好的应用需要谨慎地使用电能。用户往往会删除耗电量大的应用。
CPU外,耗电量高、值得关注的硬件模块还包括:网络硬件、蓝牙、GPS、麦克风、加速计、摄像头、扬声器和屏幕。

3.1 网路

智能的网络访问管理可以让应用响应得更快,并有助于延长电池寿命。在无法访问网络时,应当推迟后续的网络请求,直到网络连接恢复为止。
此外,应避免在没有链接WIFI的情况下进行高带宽消耗的操作,比如视频流。众所周知,蜂窝无线系统(LTE4G3G等)对电量的消耗远大于WIFI信号。根源在于LTE设备基于多输入、多输出技术,使用多个并发信号以维护两端的LTE链接。类似地,所有的蜂窝数据连接都会定期扫描以寻找更强的信号。
因此,我们需要:

  • 在进行任何网络操作之前,先检查合适的网络连接是否可用;
  • 持续监视网络的可用性,并在连接状态发生变化时给予适当的反馈。

3.2 定位管理器和GPS

了解定位服务包括GPS(或GLONASS)和WIFI硬件这一点很重要,同时要知道定位服务需要大量的电量。
使用GPS计算坐标需要确定两点信息。

  • 时间锁
    每个GPS卫星没毫秒广播唯一一个1023位随机数,因而数据传播速率是1024Mbits/sGPS的接收芯片必须正确与卫星的时间锁槽对齐。
  • 频率锁
    GPS接收器必须计算由接收器与卫星的相对运动导致的多普勒偏移带来的信号误差。
    通常情况下,锁定一个卫星至少需要30秒。必须锁定接收范围内的所有卫星。确定的卫星越多,取得的定位坐标越精确。
    计算坐标会不断地使用CPUGPS的硬件资源,因此他们会迅速地消耗电池电量。
3.2.1 最佳的初始化

在调用startUpdatingLocation方法时,两个参数起着非常重要的作用。

  • distanceFilter
    只要设备的移动超过了最小距离,距离过滤器就会导致管理器对委托对象的locationManager:didUpdateLocations:事件通知发送变化。
    这并不会有助于减少GPS接收器的使用,但会影响应用的处理速度,从而直接减少CPU的使用。
  • desiredAccuracy
    精度参数的使用直接影响了使用天线的个数,进而影响了对电池的消耗。精度级别的选取取决于应用的具体用途。
    总结
    距离过滤器只是软件层面的过滤器,而精度级别会影响物理天线的使用。当委托的回调方法locationManager:didUpdateLocations:被调用时,使用距离范围更广的过滤器只会影响间隔。另一方面,更高的精度级别意味着更多的活动天线,这会消耗更多的能量。
3.2.2 关闭无关紧要的特性

判断何时需要跟踪位置的变化。在需要跟踪时调用startUpdatingLocation方法,无需跟踪时调用stopUpdatingLocation方法。

3.2.3 只在必要时使用网络
3.2.4 后台定位服务
3.2.5 NSTimer NSThread和定位服务

当应用位于后台时,任何定时器或线程都会挂起。但如果你在应用位于后台状态时申请了定位,那么应用会在每次收到更新后被短暂唤醒。在此期间,线程和计时器都会被唤醒。可怕之处在于,如果你在这段时间做了任何网络操作,则会启动所有相关的天线(如WIFILTE/4G/3G)。

3.2.6 在应用关闭后重启

3.3 屏幕

屏幕非常耗电。屏幕越大就越费电。当然,如果你的应用在前台运行且与用户进行交互,则势必会使用屏幕并消耗电量。

3.3.1 动画

你可以遵守一个简单的规则:当应用在前台时使用动画,一旦应用进入后台则立即暂停动画。通常来说,你可以通过监听UIApplicationWillResignActiveNotificationUIApplicationDidEnterBackgroundNotification的通知事件来暂停或停止动画,也可以通过监听UIApplicationDidBecomeActiveNotification的通知事件来恢复动画。

3.3.2 视频播放

在视频播放期间,最好强制保持屏幕常亮。可以使用UIApplication对象的idleTimerDisabled属性来实现这个目的。一旦设置为YES,它会阻止屏幕休眠,从而实现常亮。
与动画类似,你可以通过响应应用的通知来释放和获取锁。

3.3.3 多屏幕

3.4 其他硬件

当应用进入后台时,应该释放对这些硬件的锁定:

  • 蓝牙
  • 相机
  • 扬声器,除非应用是音乐类的
  • 麦克风
    我们并不会在这里讨论这些硬件的特性,但是基本规则是一致的---只有当应用处于前台时才与这些硬件进行交互,应用处于后台时应停止交互。
    扬声器和无线蓝牙可能是例外。如果你正在开发音乐、收音机或其他的音频类应用,则需要在应用进入后台后继续使用扬声器。不要让屏幕仅仅为音频播放的目的而保持常亮。类似地,若应用还有未完成的数据传输,则需要在应用进入后台持续使用无线蓝牙,例如,与其他设备传输文件。

3.5 电池电量与代码感知

一个智能的应用会考虑到电池的电量和自身的状态,从而决定是否要真正执行资源密集消耗型的操作。另外一个有价值的点是对充电的判断,确定设备是否处于充电状态。
使用UIDevice实例可以获取batteryLevelbatteryState(充电状态)。ceedWithMinLevel:方法传入执行特定操作需要的最低电量级别。该级别是浮点数,范围在0~100(100表示电池完全充满)。
代码如下:

- (BOOL)shouldProceedWithMinLevel:(NSUInteger)minLevel {
    
    UIDevice *device = [UIDevice currentDevice];
    device.batteryMonitoringEnabled = YES;
    
    UIDeviceBatteryState state = device.batteryState;
    if (state == UIDeviceBatteryStateCharging || state == UIDeviceBatteryStateFull) {  // ①
        
        return YES;
    }
    
    NSUInteger batteryLevel = (NSUInteger)(device.batteryLevel * 100);// ②
    if (batteryLevel >= minLevel) {
        
        return YES;
    }
    
    return NO;
}

① 在充电或电池已经充满的情况下,任何操作都可以执行。
UIDevice返回的batteryLevel的范围在0.00~1.00

你可能感兴趣的:(iOS性能优化(三)能耗)