Flutter信息获取与分析插件infospect的使用

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

Flutter信息获取与分析插件Infospect的使用

概述

Infospect(信息检查器)是一个用于Flutter的插件,它为开发者提供了调试网络调用和应用日志的功能。通过允许开发者监控和拦截网络请求,可以高效地调试网络相关的问题并优化应用程序性能。此外,它的日志记录和调试功能有助于理解应用行为并检测错误,从而加快Bug修复速度。

预览

以下是Infospect在不同平台上的预览效果:

  • iOS: iOS
  • macOS - 在新窗口中打开Infospect: macOS
  • Linux (Ubuntu VM in mac) - 在新窗口中打开Infospect: Linux
  • Windows 10 - (VM in mac) - 在新窗口中打开Infospect: Windows

开始使用

添加依赖

首先,在pubspec.yaml文件中添加Infospect依赖项:

dependencies:
  infospect: latest-version

或者运行以下命令:

flutter pub add infospect

使用方法

初始化插件

main.dart中初始化插件:

void main(List<String> args) {
  WidgetsFlutterBinding.ensureInitialized();
  Infospect.ensureInitialized(logAppLaunch: true).handleMainWindowReceiveData();

  Infospect.instance.run(args, myApp: const MainApp());
}

添加网络调用拦截器

Dio:

_dio = Dio(BaseOptions());
_dio.interceptors.add(Infospect.instance.dioInterceptor);

Http:

http.Client client = http.Client();
client = Infospect.instance.httpClientInterceptor(client: client);

添加日志记录

Infospect.instance.addLog(
  InfospectLog(
    message: logMessage,
    level: level,
    error: error,
    stackTrace: stackTrace,
  ),
);

添加Invoker以显示覆盖按钮

可以通过包装MaterialApp中的子组件来添加Invoker,这样Invoker将出现在所有屏幕中:

MaterialApp(
  navigatorKey: Infospect.instance.getNavigatorKey,
  theme: ThemeData(useMaterial3: true),
  darkTheme: ThemeData.dark(useMaterial3: true),
  themeMode: ThemeMode.dark,
  builder: (context, child) {
    return InfospectInvoker(
      state: InvokerState.collapsible,
      child: child ?? const SizedBox.shrink(),
    );
  },
  home: const MainApp(),
)

示例Demo

以下是一个完整的示例代码,展示了如何使用Infospect进行网络调用和日志记录:

import 'dart:async';
import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:infospect/infospect.dart';

void main(List<String> args) {
  WidgetsFlutterBinding.ensureInitialized();
  Infospect.ensureInitialized(logAppLaunch: true).handleMainWindowReceiveData();
  Infospect.instance.run(args, myApp: const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  [@override](/user/override)
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> with AppLoggerMixin, AppNetworkCall {
  late Dio _dio;
  late Client _client;
  int radioValue = 1;

  [@override](/user/override)
  void initState() {
    _dio = Dio(BaseOptions(followRedirects: false));
    _dio.interceptors.add(Infospect.instance.dioInterceptor);

    _client = Client();
    _client = Infospect.instance.httpClientInterceptor(client: _client);

    super.initState();
  }

  [@override](/user/override)
  String get tag => 'MainApp';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: Infospect.instance.getNavigatorKey,
      theme: ThemeData(useMaterial3: true),
      darkTheme: ThemeData.dark(useMaterial3: true),
      themeMode: ThemeMode.dark,
      builder: (context, child) {
        return InfospectInvoker(
          state: InvokerState.collapsible,
          child: child ?? const SizedBox.shrink(),
        );
      },
      home: Scaffold(
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Text('Select a network library to test'),
                _RadioGroup(
                  radioValue: radioValue,
                  onRadioValueChanged: onRadioValueChanged,
                ),
                SizedBox(
                  width: double.maxFinite,
                  child: ElevatedButton(
                    onPressed: _onPressed,
                    child: const Text('Click here to test'),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  void onRadioValueChanged(value) {
    if (value != null) {
      setState(() {
        radioValue = value;
      });
    }
  }

  void _onPressed() {
    Timer.periodic(const Duration(seconds: 2), (timer) {
      if (timer.tick >= 8) {
        timer.cancel();
      }

      if (radioValue == 1) {
        dioCall(dio: _dio, index: timer.tick);
      } else {
        httpCall(httpClient: _client, index: timer.tick);
      }

      log(
        DiagnosticLevel.values[timer.tick],
        'test log ${timer.tick}',
        error: _getError(timer.tick),
        stackTrace: StackTrace.current,
      );
    });
  }

  String _getError(int tick) {
    String error = '';
    for (int i = 0; i < tick; i++) {
      error += 'Error ';
    }
    return error;
  }
}

class _RadioGroup extends StatelessWidget {
  const _RadioGroup({
    required this.radioValue,
    required this.onRadioValueChanged,
  });

  final int radioValue;
  final void Function(int? value) onRadioValueChanged;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Row(
      children: [
        Flexible(
          child: RadioListTile(
            value: 1,
            groupValue: radioValue,
            onChanged: onRadioValueChanged,
            title: const Text('Dio'),
          ),
        ),
        Flexible(
          child: RadioListTile(
            value: 2,
            groupValue: radioValue,
            onChanged: onRadioValueChanged,
            title: const Text('Http'),
          ),
        )
      ],
    );
  }
}

mixin AppNetworkCall {
  Future<dynamic> dioCall({required Dio dio, required index}) async {
    final val = (
      'https://official-joke-api.appspot.com/random_joke?client=dio',
      Options(headers: {'content-type': 'json'}),
      {'id': index},
    );

    switch (Method.values[(index - 1)]) {
      case Method.get:
        return dio.get(val.$1, options: val.$2, queryParameters: val.$3);
      // 其他方法类似...
    }
  }

  Future<dynamic> httpCall({required Client httpClient, required index}) async {
    final val = (
      Uri.parse('https://official-joke-api.appspot.com/random_joke?client=http&id=$index'),
      {'id': '$index'}
    );

    switch (Method.values[(index - 1)]) {
      case Method.get:
        return httpClient.get(val.$1);
      // 其他方法类似...
    }
  }
}

mixin AppLoggerMixin {
  String get tag;

  void log(DiagnosticLevel level, String message, {Object? error, StackTrace? stackTrace}) {
    Infospect.instance.addLog(
      InfospectLog(
        message: '[$tag]: $message',
        level: level,
        error: error,
        stackTrace: stackTrace,
      ),
    );
  }
}

更多关于Flutter信息获取与分析插件infospect的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter信息获取与分析插件infospect的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用infospect插件进行信息获取与分析的示例代码。infospect是一个假定的插件名称,实际中你可能需要查找并使用具体存在的类似功能的插件。为了演示,这里假设infospect插件提供了获取设备信息和进行基本分析的功能。

首先,确保你已经在pubspec.yaml文件中添加了infospect依赖:

dependencies:
  flutter:
    sdk: flutter
  infospect: ^1.0.0  # 假设版本号为1.0.0,请根据实际版本调整

然后,运行flutter pub get来安装依赖。

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

import 'package:flutter/material.dart';
import 'package:infospect/infospect.dart';  // 导入infospect插件

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Infospect Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: InfoScreen(),
    );
  }
}

class InfoScreen extends StatefulWidget {
  @override
  _InfoScreenState createState() => _InfoScreenState();
}

class _InfoScreenState extends State<InfoScreen> {
  String _deviceInfo = '';
  String _analysisResult = '';

  @override
  void initState() {
    super.initState();
    _getInfo();
  }

  Future<void> _getInfo() async {
    Infospect infospect = Infospect();

    try {
      // 获取设备信息
      var deviceInfo = await infospect.getDeviceInfo();
      setState(() {
        _deviceInfo = deviceInfo.toString();
      });

      // 进行信息分析(假设插件提供了此方法)
      var analysisResult = await infospect.analyzeInfo(deviceInfo);
      setState(() {
        _analysisResult = analysisResult.toString();
      });
    } catch (e) {
      print('Error getting info: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Infospect Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Device Information:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            SizedBox(height: 8),
            Text(_deviceInfo, style: TextStyle(fontSize: 16)),
            SizedBox(height: 24),
            Text('Analysis Result:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            SizedBox(height: 8),
            Text(_analysisResult, style: TextStyle(fontSize: 16)),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 导入infospect插件:在文件顶部导入插件。
  2. 创建Flutter应用:使用MaterialApp创建一个基本的Flutter应用。
  3. 创建主屏幕InfoScreen是一个有状态的小部件,用于显示设备信息和分析结果。
  4. 获取和分析信息:在_getInfo方法中,使用Infospect实例的getDeviceInfo方法获取设备信息,并使用analyzeInfo方法进行信息分析(假设此方法存在)。
  5. 更新UI:使用setState方法更新UI以显示获取到的设备信息和分析结果。

请注意,Infospect类及其方法(如getDeviceInfoanalyzeInfo)是假设存在的。在实际使用中,你需要参考具体插件的文档来了解其API和使用方法。如果infospect插件不存在,你可能需要寻找其他提供类似功能的插件,或者自己实现这些功能。

回到顶部