Flutter资源监控插件resource_monitor的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter资源监控插件resource_monitor的使用

resource_monitor 是一个用于在Android和iOS设备上监控CPU和内存使用的Flutter插件。本文将详细介绍如何使用该插件,并提供一个完整的示例Demo。

功能概述

  • CPU和内存使用情况:监控应用的CPU和内存使用情况。
  • 实时数据:通过定时器定期获取最新的资源使用情况。
  • 峰值记录:记录应用运行过程中的CPU和内存使用峰值。

TODO

  • ❌ 返回系统整体的CPU和内存使用情况。
  • ❌ 实现Android端的插件功能。
  • ❌ 添加Android和iOS的监听支持(EventChannel)。
  • ❌ 更新README.md文档。

示例代码

以下是一个完整的示例代码,展示了如何使用 resource_monitor 插件来监控应用的CPU和内存使用情况。

示例代码

import 'dart:math';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:resource_monitor/resource_monitor.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Resource? _data;
  static const double _defaultValue = 0.0;
  double _appCpuUsagePeak = _defaultValue, _appMemoryUsagePeak = _defaultValue;
  Timer? timer;

  [@override](/user/override)
  void initState() {
    super.initState();
    timer = Timer.periodic(const Duration(seconds: 1), (Timer t) => _getResource());
  }

  [@override](/user/override)
  void dispose() {
    timer?.cancel();
    super.dispose();
  }

  Future<void> _getResource() async {
    try {
      final data = await ResourceMonitor.getResourceUsage;

      _appCpuUsagePeak = data.cpuInUseByApp > _appCpuUsagePeak
          ? data.cpuInUseByApp
          : _appCpuUsagePeak;
      _appMemoryUsagePeak = data.memoryInUseByApp > _appMemoryUsagePeak
          ? data.memoryInUseByApp
          : _appMemoryUsagePeak;
      setState(() => _data = data);
    } on PlatformException {
      throw PlatformException(
          code: 'Unknow-error', message: 'getResourceUsage');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) => MaterialApp(
      home: Scaffold(
          appBar: AppBar(title: const Text('Plugin example app')),
          body: Center(
              child: _data != null
                  ? Table(
                      defaultColumnWidth: const FixedColumnWidth(120.0),
                      border: TableBorder.all(
                          color: Colors.black,
                          style: BorderStyle.solid,
                          width: 2),
                      children: [
                          TableRow(children: [
                            Column(children: const [
                              Text('Resource', style: TextStyle(fontSize: 20.0))
                            ]),
                            Column(children: const [
                              Text('App', style: TextStyle(fontSize: 20.0))
                            ])
                          ]),
                          TableRow(children: [
                            Column(children: const [Text('RAM - Live')]),
                            Column(children: [
                              Text(formatBytes(_data!.memoryInUseByApp.toInt(), 2))
                            ])
                          ]),
                          TableRow(children: [
                            Column(children: const [Text('CPU - Live')]),
                            Column(children: [
                              Text('${_data?.cpuInUseByApp.floorToDouble()} %')
                            ])
                          ]),
                          TableRow(children: [
                            Column(children: const [Text('RAM - Peak')]),
                            Column(children: [
                              Text(formatBytes(_appMemoryUsagePeak.toInt(), 2))
                            ])
                          ]),
                          TableRow(children: [
                            Column(children: const [Text('CPU - Peak')]),
                            Column(children: [Text('$_appCpuUsagePeak')]),
                          ])
                        ])
                  : const CircularProgressIndicator()),
          floatingActionButton: FloatingActionButton(
              child: const Icon(Icons.memory), onPressed: _getResource)));
}

String formatBytes(int bytes, int decimals) {
  if (bytes <= 0) return "0 B";
  const suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
  var i = (log(bytes) / log(1024)).floor();
  return ((bytes / pow(1024, i)).toStringAsFixed(decimals)) + ' ' + suffixes[i];
}

代码说明

  1. 导入依赖

    import 'dart:math';
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'package:flutter/services.dart';
    import 'package:resource_monitor/resource_monitor.dart';
    
  2. 初始化状态

    class _MyAppState extends State<MyApp> {
      Resource? _data;
      static const double _defaultValue = 0.0;
      double _appCpuUsagePeak = _defaultValue, _appMemoryUsagePeak = _defaultValue;
      Timer? timer;
    
      [@override](/user/override)
      void initState() {
        super.initState();
        timer = Timer.periodic(const Duration(seconds: 1), (Timer t) => _getResource());
      }
    
      [@override](/user/override)
      void dispose() {
        timer?.cancel();
        super.dispose();
      }
    
  3. 获取资源使用情况

    Future<void> _getResource() async {
      try {
        final data = await ResourceMonitor.getResourceUsage;
    
        _appCpuUsagePeak = data.cpuInUseByApp > _appCpuUsagePeak
            ? data.cpuInUseByApp
            : _appCpuUsagePeak;
        _appMemoryUsagePeak = data.memoryInUseByApp > _appMemoryUsagePeak
            ? data.memoryInUseByApp
            : _appMemoryUsagePeak;
        setState(() => _data = data);
      } on PlatformException {
        throw PlatformException(
            code: 'Unknow-error', message: 'getResourceUsage');
      }
    }
    
  4. 构建UI

    [@override](/user/override)
    Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
            appBar: AppBar(title: const Text('Plugin example app')),
            body: Center(
                child: _data != null
                    ? Table(
                        defaultColumnWidth: const FixedColumnWidth(120.0),
                        border: TableBorder.all(
                            color: Colors.black,
                            style: BorderStyle.solid,
                            width: 2),
                        children: [
                            TableRow(children: [
                              Column(children: const [
                                Text('Resource', style: TextStyle(fontSize: 20.0))
                              ]),
                              Column(children: const [
                                Text('App', style: TextStyle(fontSize: 20.0))
                              ])
                            ]),
                            TableRow(children: [
                              Column(children: const [Text('RAM - Live')]),
                              Column(children: [
                                Text(formatBytes(_data!.memoryInUseByApp.toInt(), 2))
                              ])
                            ]),
                            TableRow(children: [
                              Column(children: const [Text('CPU - Live')]),
                              Column(children: [
                                Text('${_data?.cpuInUseByApp.floorToDouble()} %')
                              ])
                            ]),
                            TableRow(children: [
                              Column(children: const [Text('RAM - Peak')]),
                              Column(children: [
                                Text(formatBytes(_appMemoryUsagePeak.toInt(), 2))
                              ])
                            ]),
                            TableRow(children: [
                              Column(children: const [Text('CPU - Peak')]),
                              Column(children: [Text('$_appCpuUsagePeak')]),
                            ])
                          ])
                    : const CircularProgressIndicator()),
            floatingActionButton: FloatingActionButton(
                child: const Icon(Icons.memory), onPressed: _getResource)));
    
  5. 格式化字节

    String formatBytes(int bytes, int decimals) {
      if (bytes <= 0) return "0 B";
      const suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
      var i = (log(bytes) / log(1024)).floor();
      return ((bytes / pow(1024, i)).toStringAsFixed(decimals)) + ' ' + suffixes[i];
    }
    

贡献

欢迎提交Pull Request。对于重大更改,请先创建一个Issue进行讨论。

请确保在适当的情况下更新测试用例。

许可证

MIT License - 查看许可证

希望这个示例能帮助你更好地理解和使用 resource_monitor 插件。如果有任何问题或建议,欢迎随时提出。


更多关于Flutter资源监控插件resource_monitor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter资源监控插件resource_monitor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter资源监控插件resource_monitor的代码案例。这个插件允许你监控设备的CPU、内存使用情况以及电池状态等。

首先,你需要在pubspec.yaml文件中添加resource_monitor依赖:

dependencies:
  flutter:
    sdk: flutter
  resource_monitor: ^latest_version  # 请替换为实际的最新版本号

然后,运行flutter pub get来获取依赖。

接下来,在你的Flutter应用中,你可以按照以下方式使用resource_monitor插件:

import 'package:flutter/material.dart';
import 'package:resource_monitor/resource_monitor.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late ResourceMonitor _resourceMonitor;
  late StreamSubscription<CpuUsageData> _cpuSubscription;
  late StreamSubscription<MemoryUsageData> _memorySubscription;
  late StreamSubscription<BatteryStatusData> _batterySubscription;

  @override
  void initState() {
    super.initState();
    _resourceMonitor = ResourceMonitor();

    // 监听CPU使用情况
    _cpuSubscription = _resourceMonitor.cpuUsage.listen((CpuUsageData data) {
      print('CPU Usage: ${data.userPercentage}% user, ${data.systemPercentage}% system');
    });

    // 监听内存使用情况
    _memorySubscription = _resourceMonitor.memoryUsage.listen((MemoryUsageData data) {
      print('Memory Usage: ${data.usedBytes} bytes used, ${data.totalBytes} bytes total');
    });

    // 监听电池状态
    _batterySubscription = _resourceMonitor.batteryStatus.listen((BatteryStatusData data) {
      print('Battery Status: ${data.level}% level, ${data.isCharging ? 'Charging' : 'Not Charging'}');
    });
  }

  @override
  void dispose() {
    // 取消订阅
    _cpuSubscription.cancel();
    _memorySubscription.cancel();
    _batterySubscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Resource Monitor Demo'),
        ),
        body: Center(
          child: Text('Check the console for resource monitor data.'),
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个Flutter应用,并在initState方法中初始化了ResourceMonitor实例,并订阅了CPU使用情况、内存使用情况和电池状态的流。每当数据发生变化时,相应的监听器会打印出最新的数据。

请注意,由于资源监控数据是实时变化的,因此在控制台中你会看到不断更新的数据输出。

此外,别忘了在dispose方法中取消订阅,以避免内存泄漏。

这个示例展示了如何使用resource_monitor插件来获取设备的资源使用情况。根据你的需求,你可以进一步处理这些数据,例如在UI中显示它们,或者根据资源使用情况触发某些操作。

回到顶部