nian_toolkit
应用内调试工具箱(Dev Toolkit),通过悬浮球在任意页面唤起菜单,提供网络请求查看、日志查看、设备信息、文件管理、数据库查看、路由记录、性能/帧率等能力。
这是一个以 Flutter 侧实现为主的工具包,适合在 Debug/QA 环境中集成。
特性
- 悬浮球/菜单:拖拽吸边、图标拖动排序、清除缓存(重置悬浮球位置并清空代理配置)
- 网络请求面板:配合
DioInspectorInterceptor记录并展示请求列表 - 代理配置:保存代理开关与地址(是否应用到网络层需要你在项目里接入)
- 日志面板:可读取/清空按天生成的日志文件(配合
autoCollectLogs自动采集) - 设备与应用信息:device_info_plus / package_info_plus 等信息展示
- 文件管理:基于应用沙盒目录浏览
- 数据库查看:基于 sqflite + sqlite_viewer2
- 路由记录:配合
RouteHistoryObserver展示路由栈与历史 - Widget 信息/详情:仅在 Debug 模式下显示(
kDebugMode) - 颜色选择器、正则工具、对齐尺、帧率、性能等
环境要求
- Flutter:建议使用 fvm(项目内包含
.fvmrc) - Dart SDK:见 pubspec.yaml
- 平台:主要面向 iOS/Android(包含
dart:io、sqflite 等依赖,Web 不支持)
安装
推荐优先使用 pub.dev 依赖;如果是单仓或私有仓,也可以使用 path/git。
Pub 依赖
dependencies:
nian_toolkit: ^0.0.1
Git 依赖
dependencies:
nian_toolkit:
git:
url: <your-repo-url>
path: plugins/nian_toolkit
快速开始
1) 用 ToolKit.run 包裹你的 App
在 main.dart:
import 'package:flutter/material.dart';
import 'package:nian_toolkit/toolkit.dart';
void main() {
ToolKit.run(
const MyApp(),
autoCollectLogs: false,
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const Scaffold(body: Center(child: Text('Hello'))),
);
}
}
说明:
ToolKit.run()内部会调用runApp(),你的项目里不要再额外调用runApp()。- 同一进程只允许存在一个 ToolKit 实例(重复调用会抛错)。
2) 在需要时显示/隐藏工具箱
ToolKit.show(isDarkMode: false);
ToolKit.hide();
显示后会出现悬浮球:
- 点击悬浮球:打开/关闭菜单
- 拖动悬浮球:移动位置,松手自动吸边并持久化
关键能力接入
路由记录
在你自己的 MaterialApp 上挂载观察器:
import 'package:flutter/material.dart';
import 'package:nian_toolkit/toolkit.dart';
MaterialApp(
navigatorObservers: [RouteHistoryObserver()],
)
否则「路由记录」面板会为空。
网络请求面板(Dio)
给你的 Dio 添加拦截器:
import 'package:dio/dio.dart';
import 'package:nian_toolkit/toolkit.dart';
final dio = Dio();
dio.interceptors.add(DioInspectorInterceptor());
否则「网络请求」面板不会记录任何请求。
日志自动采集
启用 autoCollectLogs: true 后会通过 runZonedGuarded 捕获:
print()输出- 未捕获异常(会写入文件)
日志文件位置:ApplicationDocumentsDirectory/log/.YYYY-MM-DD.log(按天生成)。
自定义插件
实现 Pluggable 并在 ToolKit.run 的 pluginsList 中传入:
class CustomPluggable implements Pluggable {
@override
String get name => '自定义';
@override
int get index => 10000;
@override
void onTrigger() {}
@override
Widget? iconWidget() => const Icon(Icons.extension);
@override
Widget? buildWidget(BuildContext context) {
return const Scaffold(
appBar: AppBar(title: Text('自定义工具')),
body: Center(child: Text('Hello Toolkit')),
);
}
}
ToolKit.run(
const MyApp(),
pluginsList: [CustomPluggable()],
);
参考示例:example/lib/custom_plug/custom_pluggable.dart
开发与运行(fvm)
fvm install
fvm flutter pub get
cd example
fvm flutter pub get
fvm flutter run
常见问题
为什么工具箱不显示?
- 确认使用
ToolKit.run()启动应用 - 确认调用过
ToolKit.show()(默认是隐藏) - 确认没有在同一进程创建多个 ToolKit(会抛错)
为什么「路由记录」没有数据?
- 给你的
MaterialApp增加navigatorObservers: [RouteHistoryObserver()]
为什么「网络请求」面板没有数据?
- 给 Dio 增加
DioInspectorInterceptor()拦截器
代理配置是否会自动生效?
- 当前只负责保存代理配置;是否应用到你的网络层(Dio/HttpClient)需要你在项目里接入。
String proxyUrl = await ProxyUtils.instance.getProxy((url) {
AppLog.i(url == "" ? "DIRECT" : "PROXY $url", tag: "proxy");
});
「清除缓存」会清什么?
- 重置悬浮球位置
- 清空已保存的代理配置(
proxy_url/proxy_enabled)
感谢
感谢flutter_ume 提供的灵感和部分调试工具。
License
仓库内 LICENSE 目前还是占位内容,尚未补全。
Libraries
- app_theme/theme
- icons/plugin_icons
- pages/align_ruler_plug/src/align_ruler_page
- pages/app_device_info_plug/src/app_device_info_page
- pages/app_device_info_plug/src/app_info_page
- pages/app_device_info_plug/src/device_ingo_page
- pages/app_device_info_plug/src/pannel_widget
- pages/app_log_plug/src/app_log_page
- pages/color_picker_plug/src/color_picker_page
- pages/dio_plug/src/constants/constants
- pages/dio_plug/src/containers/http_container
- pages/dio_plug/src/dio_page
- pages/dio_plug/src/instances
- pages/dio_plug/src/widgets/response_card
- pages/file_manager_plug/src/file_manager_page
- pages/frame_rate_plug/src/frame_rate_page
- pages/frame_rate_plug/widget/collection_util
- pages/frame_rate_plug/widget/fps_chart
- pages/frame_rate_plug/widget/fps_info
- pages/frame_rate_plug/widget/fps_widget
- pages/frame_rate_plug/widget/performance_observer_widget
- pages/performance_plug/performance_pluggable
- pages/pluggable
- pages/proxy_plugs/src/proxy_page
- pages/route_history_plug/src/route_history_page
- pages/widget_detail_plug/widgets/search_bar
- toolkit
- toolkit/toolkit_ball
- toolkit/toolkit_widget
- utils/dio_inspector_interceptor
- utils/kit_utils
- utils/log_writer
- utils/proxy_utils
- utils/route_history_observer