iOS 电量消耗改善:一招套路及相关姿势

栏目: IOS · 发布时间: 5年前

内容简介:先使用 Xcode Energy Gauge 分析出哪一块耗电(网络和 motion , 还是定位 ... ), 用 Time Profiler 定位问题与解决 ( Instruments 模版 ), 得到用户好的反馈。比如: 网络请求,先压缩数据网络请求,使用缓存机制,设置内容验证( 需要的数据是否更新了 ),或者缓存的失效时间

先使用 Xcode Energy Gauge 分析出哪一块耗电(网络和 motion , 还是定位 ... ), 用 Time Profiler 定位问题与解决 ( Instruments 模版 ), 得到用户好的反馈。

三个原则:

  • Do it never/do it less (能不做,就不做。少做的,好)

比如: 网络请求,先压缩数据

  • Do it at a better time (合适的时机处理 )

网络请求,使用缓存机制,设置内容验证( 需要的数据是否更新了 ),或者缓存的失效时间

  • Do it efficiently ( 有效处理 )

合并网络请求。一次请求大量数据,比多次请求少量数据省电

(类比 CPU,线程开多了不好。开线程,就会有消耗)

套路很简单,将手机放在桌子上,Xcode 里面启动 app, 并检测,啥也不干。如果电量消耗较高,很不合适了

WWDC 推荐使用 Xcode Debug 栏的 Energy Debug Gauge。

( 调性能,都是用真机。机器老一点,效果更好 )

Energy Debug Gauge 形象、直观

iOS 电量消耗改善:一招套路及相关姿势

可看出,当前手机的耗电情况,耗电低、高、很高。苹果的三个阶段,有些不太细致。(左上的 Utilization, Current Impact)

app 的平均能耗,一目了然 ( 右上的 Average ) 。

每一个时刻,耗电的是什么。 CPU 、网络、文件 I/O 、定位,哪些消耗了。( 中间的 Energy Impact )

Xcode Energy Gauge 可以快速定位问题,想要进一步的细致分析,下面有各种选项,跳转到对应的 Instrumens 模版。

比如:

分析 CPU 使用的 time profile, (能够知道代码的执行情况了,根据函数的调用消耗。找出权重大的,干掉不必要的。)

分析网络活动的 network profile, 分析定位活动的 location profile

iOS 电量消耗改善:一招套路及相关姿势

本文示例代码: 解决的两个问题,给 CoreMotion 更新设置过滤,干掉频繁的日志上传

iOS 电量消耗改善:一招套路及相关姿势

这里电量消耗很高,很稳定

主要是 CPU 和网络请求在耗电。

使用 Instruments 的 Time Profiler 分析,

iOS 电量消耗改善:一招套路及相关姿势

可以先放大上面的 time line,再选择一个时间段,在调用树 call tree 中,进一步分析。

Time Profiler 的选项默认是按线程划分的,再选一个隐藏系统调用函数。

(系统执行的函数,可以参考一下,到底发生了什么。系统的改不了。可以改自己的源代码 )

iOS 电量消耗改善:一招套路及相关姿势

在调用树的表格中,按权重展开 ( weight ),要干掉的就是权重大的,耗时间的。

接着展开主线程 ( main thread 。看上图,其他线程的耗时,相比主线程的,可忽略 ), 按住 Option 键,点击 main thread 左边的小三角,可以一下子展开很多。

可清晰看出,耗时严重的是 450 毫秒左右的那一行 thunk for ... CMDeviceMotion? ...

里面调用了一个耗时的方法, CatPhotoTableViewCell.panImage , 上图, 454 毫秒中,占 419 毫秒。

iOS 电量消耗改善:一招套路及相关姿势

点击进入详情,就看到代码了。

在 CatFeedViewController 的 viewDidLoad 方法中,有一个倾斜的设置

motionManager.startDeviceMotionUpdates(to: .main, withHandler:{ deviceMotion, error in
            guard let deviceMotion = deviceMotion else { return }
            let xRotationRate = CGFloat(deviceMotion.rotationRate.x)
            let yRotationRate = CGFloat(deviceMotion.rotationRate.y)
            let zRotationRate = CGFloat(deviceMotion.rotationRate.z)
            //  y > z, 这个动作是翘起来
            //  y > x + z, 这个动作是斜着翘起来
              if abs(yRotationRate) > (abs(xRotationRate) + abs(zRotationRate)) {
                for cell in self.tableView.visibleCells as! [CatPhotoTableViewCell] {
                    cell.panImage(with: yRotationRate)
                }
              }
  })
复制代码

现在的代码显示栏 ( 原来的 Call Tree 表格 ), 右上角有一个 Xcode 的小图标,点击返回 Xcode 调试代码。

手机没动,老是调用 cell.panImage(with: yRotationRate) , 根本就没效果。

设置一下,调用 cell.panImage 的时候,要超过最小的手机幅度。幅度小,根本就没效果。 添加一个属性记录 lastY 来设置,过滤掉手机小的抖动。

private var lastY = 0.0
override func viewDidLoad() {
        super.viewDidLoad()
        ......
        motionManager.startDeviceMotionUpdates(to: .main, withHandler:{ deviceMotion, error in
            guard let deviceMotion = deviceMotion else { return }
          
            // 添加了这两行
           guard abs(self.lastY - deviceMotion.rotationRate.y) > 0.1 else { return }
            self.lastY = deviceMotion.rotationRate.y

            let xRotationRate = CGFloat(deviceMotion.rotationRate.x)
            let yRotationRate = CGFloat(deviceMotion.rotationRate.y)
            let zRotationRate = CGFloat(deviceMotion.rotationRate.z)
              if abs(yRotationRate) > (abs(xRotationRate) + abs(zRotationRate)) {
                for cell in self.tableView.visibleCells as! [CatPhotoTableViewCell] {
                    cell.panImage(with: yRotationRate)
                }
              }
        })
    }
复制代码

还有一个使用 Timer 定时发送日志的问题,CPU 根本没有空闲的时间,开销很大。

具体见文末的 Demo Code.

最后这样

iOS 电量消耗改善:一招套路及相关姿势

会慢慢降下去,至于电量低消耗。 需要大约两分钟时间,一屏幕放不下。

Instruments 的 Energy Log 有问题,连着 Xcode 实时调试的部分 gg 了

Instruments 的 Energy Log 模版用途不大

因为不能手机在线调试。Energy 是空的, 或者提示 No Data ,

这是苹果的一个长期的 bug .(参见Apple Forum )

Energy Log 模版的模块挺丰富的,可以看屏幕亮度、定位、蓝牙、GPU 和网络等等的功耗情况,其中网络又包括 WiFi 和蜂窝网络。

想着一边给手机充电,一边调试电量损失,不靠谱。

试了下,无线用 Instruments 的 Energy Log 模版调试,结果一样。

无线连接 Xcode 调试耗电,也没有数据。

无线用 Instruments 调试,首先要设置 Xcode 无线 Debug ,

无线 debug 功能,隐藏在 Xcode 的 Window > Devices and Simulators 中。

iOS 电量消耗改善:一招套路及相关姿势

实际上是,使用共享的无线网络,取代了数据线的连接,与 Xcode 建立连接。

会有一个网络的 Icon . 上面还有提示语 ( connected , 连上了 )

如下图:

iOS 电量消耗改善:一招套路及相关姿势

更多参见博客 How to use Wireless Debugging on Xcode 9

然后就可以设置 Instruments 无线设备调试了,

更多参见苹果文档 Energy Efficiency Guide for iOS Apps

instruments 的 Energy 模版,将电量消耗的程度划分为 20 个级别。 0 代表不耗电,自然 app 没做什么 20 代表耗电严重

WWDC 中说,要看到,就导入离线的 log。(几个月以前,还能用)

在手机的设置中,开发者选项中的 Logging, 选中 Energy, 点击开始录制:

iOS 电量消耗改善:一招套路及相关姿势

之后,使用你的 app 一段时间,(可以重点测耗电功能) 开发者选项中的 Logging, 点击完成录制, 导入电量消耗 log 数据,到 Instruments 的 Energy Log 模版.

iOS 电量消耗改善:一招套路及相关姿势

推测老版本的不行( 11.4 ), 没数据。操作的时候,手机的设置 app ,还老是闪退。

手机升级到最新版(12.1 , 20181127),试了多次,也不行, 猜测目前是彻底挂了

(本文中,重启过手机,升级过手机。没试过重启电脑)

湿一点,好消化

耗电是不好的。

写入硬盘与网络请求,都是高耗电操作。

网络请求特别耗电,每一个网络请求,手机设备需要使用他的蜂窝网络天线,发送无线电波。

网络的质量与类型,对于耗电的影响也很大。 使用 Wi-Fi 比 3G , 4G 要省电得多。 使用 4G 比 3G 要省电,因为 4G 的信号更强。

计时器,能不用就不用。( NSTimer )

一般情况下,app 都用 Timer 做了很多无用功。

比如, 一个列表屏幕, 上方 banner 计时器,往下滑到看不见 banner ,就可以暂停计时器。上滑,看得见 banner 了,又可以恢复 resume。

同样的,进入子界面,可以选择暂停 Timer,或者释放,...

例子: 定时做重复的大量工作不好,可能每当系统休眠(系统要降低能级了),系统又被唤醒了,开始功耗。

定位

与网络请求类似,手机设备定位通过 GPS 天线发送信号,也挺耗电的。

如果 app 经常去获取手机设备的精确定位,定位精度越高,能耗越严重。 建议使用策略,手机的负担会小很多。

( :chestnut:,Deferred location updates, 位置更新延迟(直到移动了 x 米或者时间超过了 xx 秒 )、

significant location change, 定位变化比较大的时候,唤醒、

region monitoring, 监测用户进入或离开特定地理区域)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

只是为了好玩

只是为了好玩

Linus Torvalds、David Diamond / 陈少芸 / 人民邮电出版社 / 2014-7 / 49.00 元

本书是Linux之父Linus Torvalds的自传。 Linux之父Linus Torvalds的自传,也是Linus唯一一本书。Linus以调侃的语气讲述了自己的成长经历,在他看来,一切都是为了好玩儿,兴趣引发革命。书中内容共分为五章,一部分是Linus自己写的,一部分是合著者David Diamond的评论。 林纳斯•托瓦兹 当今世界最著名的程序员、黑客,开源操作系统Linux......一起来看看 《只是为了好玩》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具