美文网首页
18 | 怎么减少 App 电量消耗?

18 | 怎么减少 App 电量消耗?

作者: 阳明先生x | 来源:发表于2020-07-07 10:25 被阅读0次

    在iOS中,IOKit framework 是专门用于跟硬件或内核服务通信的。所以,我们可以通过IOKit framework 来获取硬件信息,进而获取到电量消耗信息。在使用IOKit framework时,你需要:
    首先,把IOPowerSources.h、IOPSKeys.h和IOKit 这三个文件导入到工程中;
    然后,把batteryMonitoringEnabled置为true;
    最后,通过如下代码获取1%精确度的电量信息。

    #import "IOPSKeys.h"
    #import "IOPowerSources.h"
    
    -(double) getBatteryLevel{
        // 返回电量信息
        CFTypeRef blob = IOPSCopyPowerSourcesInfo();
        // 返回电量句柄列表数据
        CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
        CFDictionaryRef pSource = NULL;
        const void *psValue;
        // 返回数组大小
        int numOfSources = CFArrayGetCount(sources);
        // 计算大小出错处理
        if (numOfSources == 0) {
            NSLog(@"Error in CFArrayGetCount");
            return -1.0f;
        }
    
        // 计算所剩电量
        for (int i=0; i<numOfSources; i++) {
            // 返回电源可读信息的字典
            pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
            if (!pSource) {
                NSLog(@"Error in IOPSGetPowerSourceDescription");
                return -1.0f;
            }
            psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));
    
            int curCapacity = 0;
            int maxCapacity = 0;
            double percentage;
    
            psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
            CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
    
            psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
            CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);
    
            percentage = ((double) curCapacity / (double) maxCapacity * 100.0f);
            NSLog(@"curCapacity : %d / maxCapacity: %d , percentage: %.1f ", curCapacity, maxCapacity, percentage);
            return percentage;
        }
        return -1.
    
    // 轮询检查多个线程 CPU 情况
    + (void)updateCPU {
        thread_act_array_t threads;
        mach_msg_type_number_t threadCount = 0;
        const task_t thisTask = mach_task_self();
        kern_return_t kr = task_threads(thisTask, &threads, &threadCount);
        if (kr != KERN_SUCCESS) {
            return;
        }
        for (int i = 0; i < threadCount; i++) {
            thread_info_data_t threadInfo;
            thread_basic_info_t threadBaseInfo;
            mach_msg_type_number_t threadInfoCount = THREAD_INFO_MAX;
            if (thread_info((thread_act_t)threads[i], THREAD_BASIC_INFO, (thread_info_t)threadInfo, &threadInfoCount) == KERN_SUCCESS) {
                threadBaseInfo = (thread_basic_info_t)threadInfo;
                if (!(threadBaseInfo->flags & TH_FLAGS_IDLE)) {
                    integer_t cpuUsage = threadBaseInfo->cpu_usage / 10;
                    if (cpuUsage > 90) {
                        //cup 消耗大于 90 时打印和记录堆栈
                        NSString *reStr = smStackOfThread(threads[i]);
                        //记录数据库中
                        [[[SMLagDB shareInstance] increaseWithStackString:reStr] subscribeNext:^(id x) {}];
                        NSLog(@"CPU useage overload thread stack:\n%@",reStr);
                    }
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:18 | 怎么减少 App 电量消耗?

          本文链接:https://www.haomeiwen.com/subject/nwaoqktx.html