Flutter日志记录与Redux调试插件redux_logging的使用

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

Flutter日志记录与Redux调试插件redux_logging的使用

redux_logging

Build Status codecov

redux_logging连接了一个Logger到一个Redux Store。它也可以简单地打印最新的状态和动作变化。

默认情况下,这个类不会在你的控制台或终端上打印任何内容,也不会将数据发送到类似Fabric或Sentry这样的Web服务。它只是将条目记录到一个Logger实例中。

如果你想简单地将最新的动作和状态打印到你的控制台或终端,可以创建一个new LoggingMiddleware.printer()并将其传递给Store创建时。

如果你希望对日志数据的发送位置有更多的控制权,你可以监听你的Logger的onRecord Stream。

Dart 版本

  • Dart 1 支持: 0.1.x
  • Dart 2 支持: 0.2.x+

简单打印示例

如果你想要一种简单的方法来打印分发的动作到你的控制台/终端,可以使用new LoggingMiddleware.printer()工厂方法。

注意: LoggingMiddleware需要是中间件列表中的最后一个。

import "package:redux/redux.dart";
import 'package:redux_logging/redux_logging.dart';

final store = new Store<int>(
  (int state, dynamic action) => state + 1,
  initialValue: 0,
  // 注意LoggingMiddleware应该放在中间件列表的最后!
  middleware: [myOtherMiddleware, new LoggingMiddleware.printer()]
);

store.dispatch("Hi"); // 打印 {Action: "Hi", Store: 1, Timestamp: ...}

示例

如果你只想将动作记录到一个Logger,并且选择如何处理输出,可以使用默认构造函数。

import 'package:logging/logging.dart';
import "package:redux/redux.dart";
import 'package:redux_logging/redux_logging.dart';

// 创建你自己的Logger
final logger = new Logger("Redux Logger");

// 将其传递给你的中间件
final middleware = new LoggingMiddleware(logger: logger);
final store = new Store<int>(
  (int state, dynamic action) => state + 1,
  initialState: 0,
  middleware: [middleware],
);

// 注意:监听一个logger实例的一个特点是,实际上你是在监听*所有*logger的单例实例。
logger.onRecord
  // 过滤出发送到你的logger实例的[LogRecord]
  .where((record) => record.loggerName == logger.name)
  // 打印它们(或者做一些更有趣的事情!)
  .listen((loggingMiddlewareRecord) => print(loggingMiddlewareRecord));

格式化日志消息

这个库自带两个格式化程序:

  • LoggingMiddleware.singleLineFormatter
  • LoggingMiddleware.multiLineFormatter

你可以通过实现自己的MessageFormatter并将其传递给LoggingMiddleware构造函数来可选地控制将要记录的消息的格式。它是一个简单的函数,接受三个参数:State、Action和Timestamp。

格式化示例

import "package:redux/redux.dart";
import 'package:redux_logging/redux_logging.dart';

// 创建一个只打印分发动作的格式化器
String onlyLogActionFormatter<State>(
  State state,
  dynamic action,
  DateTime timestamp,
) {
  return "{Action: $action}";
}

// 使用格式化器创建你的中间件。
final middleware = new LoggingMiddleware(formatter: onlyLogActionFormatter);

// 将带有格式化器的中间件添加到你的Store
final store = new Store<int>(
  (int state, dynamic action) => state + 1,
  initialState: 0,
  middleware: [middleware],
);

完整示例Demo

为了提供一个完整的演示,以下是一个整合了上述所有概念的完整Flutter应用示例。

import 'package:flutter/material.dart';
import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart';
import 'package:logging/logging.dart';

void main() {
  // 创建你自己的Logger
  final logger = Logger('Redux Logger');

  // 创建一个格式化器,以便自定义日志输出
  String customFormatter<State>(State state, dynamic action, DateTime timestamp) {
    return "Custom Log - Action: $action, State: $state, Timestamp: $timestamp";
  }

  // 创建中间件
  final middleware = LoggingMiddleware(
    logger: logger,
    formatter: customFormatter,
  );

  // 创建Store
  final store = Store<int>(
    (int state, dynamic action) => state + 1,
    initialState: 0,
    middleware: [middleware],
  );

  // 监听日志记录
  logger.onRecord.listen((record) {
    if (record.loggerName == logger.name) {
      print(record.message);
    }
  });

  runApp(MyApp(store: store));
}

class MyApp extends StatelessWidget {
  final Store<int> store;

  MyApp({required this.store});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Redux Logging Demo',
      home: Scaffold(
        appBar: AppBar(title: Text('Redux Logging Demo')),
        body: ReduxLoggingDemo(store: store),
      ),
    );
  }
}

class ReduxLoggingDemo extends StatefulWidget {
  final Store<int> store;

  ReduxLoggingDemo({required this.store});

  @override
  _ReduxLoggingDemoState createState() => _ReduxLoggingDemoState();
}

class _ReduxLoggingDemoState extends State<ReduxLoggingDemo> {
  @override
  void initState() {
    super.initState();
    widget.store.dispatch("Initial Dispatch");
  }

  void _incrementCounter() {
    widget.store.dispatch("Increment Counter");
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'You have pushed the button this many times:',
          ),
          Text(
            '${widget.store.state}',
            style: Theme.of(context).textTheme.headline4,
          ),
          ElevatedButton(
            onPressed: _incrementCounter,
            child: Text('Increment'),
          ),
        ],
      ),
    );
  }
}

在这个完整的示例中,我们创建了一个简单的Flutter应用程序,它使用Redux管理状态,并通过redux_logging插件记录每个动作和状态的变化。每当点击“Increment”按钮时,都会触发一个动作,该动作会增加状态值,并且日志会被打印出来。


更多关于Flutter日志记录与Redux调试插件redux_logging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter日志记录与Redux调试插件redux_logging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是如何在Flutter项目中使用日志记录和Redux调试插件redux_logging的详细代码示例。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加redux_logginglogging依赖:

dependencies:
  flutter:
    sdk: flutter
  redux: ^5.0.0  # 确保你使用的redux版本与redux_logging兼容
  redux_logging: ^0.4.0  # 检查最新版本
  logging: ^1.0.0

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

2. 配置日志记录

在你的Flutter项目的入口文件(通常是main.dart)中配置日志记录:

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart';

// 配置日志记录器
final Logger logger = Logger('MyApp');

void configureLogging() {
  hierarchicalLoggingEnabled = true;
  Logger.root.level = Level.ALL;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
    if (rec.error != null && rec.stackTrace != null) {
      print(rec.error);
      print(rec.stackTrace);
    }
  });
}

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

3. 创建Redux Store并添加Logger Middleware

接下来,在你的Redux store配置中添加redux_logging的logger middleware:

import 'package:redux/redux.dart';
import 'package:redux_logging/redux_logging.dart';

// 示例Action和State
enum AppAction { increment, decrement }

class AppState {
  final int counter;

  AppState({required this.counter});

  AppState copyWith({int? counter}) {
    return AppState(counter: counter ?? this.counter);
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is AppState &&
          runtimeType == other.runtimeType &&
          counter == other.counter;

  @override
  int get hashCode => counter.hashCode;
}

AppState appReducer(AppState state, dynamic action) {
  if (action == AppAction.increment) {
    return state.copyWith(counter: state.counter + 1);
  } else if (action == AppAction.decrement) {
    return state.copyWith(counter: state.counter - 1);
  }
  return state;
}

void main() {
  configureLogging();

  final store = Store<AppState>(
    appReducer,
    initialState: AppState(counter: 0),
    middleware: [createLoggingMiddleware<AppState>()],
  );

  runApp(MyApp(store: store));
}

4. 使用Store和UI组件

最后,在你的Flutter应用中使用Redux store来管理状态,并展示UI组件:

import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';

class MyApp extends StatelessWidget {
  final Store<AppState> store;

  MyApp({required this.store});

  @override
  Widget build(BuildContext context) {
    return StoreProvider<AppState>(
      store: store,
      child: MaterialApp(
        home: CounterScreen(),
      ),
    );
  }
}

class CounterScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Redux Logging Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            StoreConnector<AppState, int>(
              converter: (store) => store.state.counter,
              builder: (context, counter) {
                return Text(
                  '$counter',
                  style: Theme.of(context).textTheme.headline4,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            onPressed: () {
              StoreProvider.of<AppState>(context).dispatch(AppAction.increment);
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
          SizedBox(height: 10),
          FloatingActionButton(
            onPressed: () {
              StoreProvider.of<AppState>(context).dispatch(AppAction.decrement);
            },
            tooltip: 'Decrement',
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

总结

以上代码展示了如何在Flutter项目中配置日志记录和使用redux_logging插件来调试Redux状态管理。通过配置日志记录器和在Redux store中添加logger middleware,你可以在控制台中看到Redux action和state的变化,帮助你更好地调试应用。

回到顶部