This commit is contained in:
魏少阳 2024-04-12 09:15:17 +08:00
commit 02419fca61
13 changed files with 915 additions and 9 deletions

View File

@ -57,7 +57,6 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
locale = const Locale('zh', 'CN');
}
}
// print("localelocalelocalelocalelocale locale:${locale} locale.languageCode:${locale.languageCode} locale.countryCode:${locale.countryCode} supportedLocales:${supportedLocales}");
AppManager()
.setLanCode(code: '${locale!.languageCode}_${locale.countryCode}');
return locale;
@ -93,7 +92,8 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
fontWeight: FontWeight.w400,
fontSize: 36.sp),
),
splashColor: Colors.transparent, //
splashColor: Colors.transparent,
//
highlightColor: Colors.transparent,
),
debugShowCheckedModeBanner: false,

View File

@ -0,0 +1,43 @@
import 'dart:async';
import 'package:rxdart/rxdart.dart';
import 'package:star_lock/debug/log.dart';
class DebugConsoleController {
final List<DebugConsoleLog> logs;
final _streamController = BehaviorSubject<List<DebugConsoleLog>>();
DebugConsoleController({ List<DebugConsoleLog>? logs }) : logs = logs ?? [];
Stream<List<DebugConsoleLog>> get stream => _streamController.stream;
void close() => _streamController.close();
void notifyUpdate() => _streamController.add(logs);
void log(
Object? message, {
DebugConsoleLevel level = DebugConsoleLevel.normal,
DateTime? timestamp,
StackTrace? stackTrace,
}) {
logs.add(
DebugConsoleLog(
message: message,
level: level,
timestamp: timestamp,
stackTrace: stackTrace,
)
);
notifyUpdate();
}
List<DebugConsoleLog> getLogsByLevel(DebugConsoleLevel level) {
return logs.where((log) => log.level == level).toList();
}
void clear() {
logs.clear();
notifyUpdate();
}
}

View File

@ -0,0 +1,426 @@
library debug_console;
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:star_lock/debug/controller.dart';
import 'package:star_lock/debug/log.dart';
import 'package:star_lock/debug/tile.dart';
import 'package:star_lock/debug/utils/scrollable.dart';
/// # Debug Console
///
/// A console for debugging Flutter apps, and displaying console messages on the widget.
///
/// Check the console for prints and errors, while you're testing it, all within your app. Make your own logging or watch for console prints.
///
/// ## Features
///
/// * Log your messages
/// * Display console messages and errors
/// * Use different levels for better emphasis
/// * Filter the logs
/// * Add extra actions to execute from the Debug Console menu
/// * Check StackTrace of errors
class DebugConsole extends StatefulWidget {
final DebugConsoleController controller;
final List<PopupMenuItem<void>> actions;
final bool expandStackTrace;
final String? savePath;
/// # Debug Console
///
/// A console for debugging Flutter apps, and displaying console messages on the widget.
///
/// Check the console for prints and errors, while you're testing it, all within your app. Make your own logging or watch for console prints.
///
/// ## Features
///
/// * Log your messages
/// * Display console messages and errors
/// * Use different levels for better emphasis
/// * Filter the logs
/// * Add extra actions to execute from the Debug Console menu
/// * Check StackTrace of errors
DebugConsole({
key,
DebugConsoleController? controller,
this.actions = const [],
this.expandStackTrace = false,
this.savePath,
}) : controller = controller ?? DebugConsole.instance;
@override
State<DebugConsole> createState() => _DebugConsoleState();
static DebugConsoleController? _instance;
static DebugConsoleController get instance {
_instance ??= DebugConsoleController(
logs: DebugConsoleLog.fromFile(DebugConsole.loadPath));
return _instance!;
}
static String loadPath = 'debug_console.log';
/// Adds a log to the root controller, attached with a message, level, timestamp and stack trace.
///
/// The default level is `DebugConsoleLogLevel.normal`.
///
/// Same as:
/// ```dart
/// DebugConsole.instance.log( ... );
/// ```
static void log(
Object? message, {
DebugConsoleLevel level = DebugConsoleLevel.normal,
DateTime? timestamp,
StackTrace? stackTrace,
}) =>
instance.log(
message,
level: level,
timestamp: timestamp,
stackTrace: stackTrace,
);
/// Clears the logs of the root controller.
///
/// Same as:
/// ```dart
/// DebugConsole.instance.clear();
/// ```
static void clear() => instance.clear();
/// Adds a log to the root controller, with the level `DebugConsoleLevel.info`.
///
/// Same as:
/// ```dart
/// DebugConsole.log(message, level: DebugConsoleLevel.info, ... );
/// ```
static void info(
Object? message, {
DateTime? timestamp,
StackTrace? stackTrace,
}) =>
log(
message,
level: DebugConsoleLevel.info,
timestamp: timestamp,
stackTrace: stackTrace,
);
/// Adds a log to the root controller, with the level `DebugConsoleLevel.warning`.
///
/// Same as:
/// ```dart
/// DebugConsole.log(message, level: DebugConsoleLevel.warning, ... );
/// ```
static void warning(
Object? message, {
DateTime? timestamp,
StackTrace? stackTrace,
}) =>
log(
message,
level: DebugConsoleLevel.warning,
timestamp: timestamp,
stackTrace: stackTrace,
);
/// Adds a log to the root controller, with the level `DebugConsoleLevel.error`.
///
/// Same as:
/// ```dart
/// DebugConsole.log(message, level: DebugConsoleLevel.error, ... );
/// ```
static void error(
Object? message, {
DateTime? timestamp,
StackTrace? stackTrace,
}) =>
log(
message,
level: DebugConsoleLevel.error,
timestamp: timestamp,
stackTrace: stackTrace,
);
/// Adds a log to the root controller, with the level `DebugConsoleLevel.fatal`.
///
/// Same as:
/// ```dart
/// DebugConsole.log(message, level: DebugConsoleLevel.fatal, ... );
/// ```
static void fatal(
Object? message, {
DateTime? timestamp,
StackTrace? stackTrace,
}) =>
log(
message,
level: DebugConsoleLevel.fatal,
timestamp: timestamp,
stackTrace: stackTrace,
);
/// Adds a log to the root controller, with the level `DebugConsoleLevel.debug`.
///
/// Same as:
/// ```dart
/// DebugConsole.log(message, level: DebugConsoleLevel.debug, ... );
/// ```
static void debug(
Object? message, {
DateTime? timestamp,
StackTrace? stackTrace,
}) =>
log(
message,
level: DebugConsoleLevel.debug,
timestamp: timestamp,
stackTrace: stackTrace,
);
/// Listen for prints and errors, to catch all messages in your app.
///
/// Everything inside that function will be automatically logged.
///
/// ```dart
/// DebugConsole.listen(() {
/// runApp(const MyApp());
/// });
/// ```
///
/// * A controller can be given, instead of logging to the root.
static void listen(void Function() body,
{DebugConsoleController? controller}) {
controller ??= DebugConsole.instance;
runZoned(body,
zoneSpecification: ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
controller!.log(line);
parent.print(zone, line);
},
handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone,
Object error, StackTrace stackTrace) {
controller!.log(error,
level: DebugConsoleLevel.error, stackTrace: stackTrace);
parent.handleUncaughtError(zone, error, stackTrace);
},
));
}
}
class _DebugConsoleState extends State<DebugConsole> {
StreamSubscription<List<DebugConsoleLog>>? subscription;
List<DebugConsoleLog> logs = [];
bool expandStackTrace = false;
bool save = true;
String filter = '';
TextEditingController? textController;
@override
void initState() {
super.initState();
textController = TextEditingController();
expandStackTrace = widget.expandStackTrace;
logs = widget.controller.logs;
subscription = widget.controller.stream.listen((logs) {
if (widget.savePath != null && save) saveToFile(logs: logs);
logs.sort((a, b) => a.timestamp.compareTo(b.timestamp));
logs = logs.reversed.toList();
setState(() => this.logs = logs);
});
}
@override
void dispose() {
subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
final filteredLogs = filter.isEmpty
? logs
: logs
.where((log) => filter.split(',').any((filter) {
filter = filter.trim();
return filter.isNotEmpty &&
log.message.toLowerCase().contains(filter.toLowerCase());
}))
.toList();
return Scaffold(
appBar: AppBar(
title: const Text('日志记录'),
actions: [
PopupMenuButton<void>(
icon: const Icon(Icons.more_vert),
itemBuilder: (context) => [
...widget.actions,
if (widget.actions.isNotEmpty) const PopupMenuDivider(),
PopupMenuItem(
child: StatefulBuilder(
builder: (context, setCheckboxState) => Row(
children: [
const Expanded(child: Text('暂停日志记录')),
Checkbox(
value: subscription!.isPaused,
onChanged: (value) =>
setCheckboxState(() => toggleLogging(!value!)),
),
],
),
),
onTap: () => toggleLogging(),
),
PopupMenuItem(
child: StatefulBuilder(
builder: (context, setCheckboxState) => Row(
children: [
const Expanded(child: Text('展开 StackTrace')),
Checkbox(
value: expandStackTrace,
onChanged: (value) => setCheckboxState(
() => setState(() => expandStackTrace = value!)),
),
],
),
),
onTap: () =>
setState(() => expandStackTrace = !expandStackTrace),
),
if (widget.savePath != null)
PopupMenuItem(
child: StatefulBuilder(
builder: (context, setCheckboxState) => Row(
children: [
const Expanded(child: Text('保存')),
Checkbox(
value: save,
onChanged: (value) {
if (value!) saveToFile();
setCheckboxState(
() => setState(() => save = value));
},
),
],
),
),
onTap: () {
if (!save) saveToFile();
setState(() => save = !save);
},
),
PopupMenuItem(
onTap: () => widget.controller.clear(),
child: const Text('清除日志'),
),
],
)
],
),
body: Stack(
children: [
logs.isEmpty
? const Padding(
padding: EdgeInsets.only(bottom: 50),
child: Center(child: Text('没有日志')),
)
: ListView.builder(
padding: const EdgeInsets.only(bottom: 75),
reverse: true,
itemCount: filteredLogs.length,
itemBuilder: (context, index) {
final log = filteredLogs[index];
return DebugConsoleTile(log,
key: ValueKey(log.timestamp),
expanded: expandStackTrace);
},
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
margin: const EdgeInsets.all(15),
child: Row(
children: [
Expanded(
child: TextField(
controller: textController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
contentPadding:
const EdgeInsets.symmetric(horizontal: 15),
hintText: 'Filter logs',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
),
onChanged: (value) => setState(() => filter = value),
),
),
const SizedBox(width: 5),
IconButton(
icon: const Icon(Icons.close),
onPressed: () {
textController!.clear();
setState(() => filter = '');
},
),
const SizedBox(width: 5),
FloatingActionButton(
tooltip: subscription!.isPaused
? 'Resume logging'
: 'Pause logging',
onPressed: () => toggleLogging(),
child: Icon(subscription!.isPaused
? Icons.play_arrow
: Icons.pause),
),
],
),
),
),
],
),
);
}
void saveToFile({List<DebugConsoleLog>? logs, String? path}) {
path ??= widget.savePath;
if (path == null) return;
logs ??= this.logs;
logs.sort((a, b) => a.timestamp.compareTo(b.timestamp));
logs = logs.reversed.toList();
final file = File(path);
if (logs.isEmpty) {
file.delete();
} else {
file.writeAsString(
logs.map((log) => log.toString()).join('\n'),
);
}
}
void toggleLogging([bool? paused]) {
paused ??= subscription!.isPaused;
setState(() {
if (paused!) {
subscription!.resume();
} else {
subscription!.pause();
}
});
}
}

View File

@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/debug/controller.dart';
import 'package:star_lock/debug/debug_console.dart';
class DeBug {
static void log(String message, {String? tag}) {
DebugConsole.info(message);
Get.log(message);
}
static bool open = false;
static bool openInfo = false;
static void showFloatWidget() {
Rx<Offset> offset = Offset(20, 100).obs; //
OverlayEntry overlayEntry = OverlayEntry(builder: (context) {
return Obx(() => Positioned(
left: offset.value.dx,
top: offset.value.dy,
child: GestureDetector(
onPanUpdate: (details) {
offset.value += details.delta;
},
child: FloatingActionButton(
child: Icon(Icons.bug_report),
onPressed: () {
if (openInfo) {
Get.back();
return;
}
if (open) {
open = false;
Get.back();
} else {
open = true;
Get.to(WillPopScope(
onWillPop: () async {
open = false;
return true;
},
child: DebugConsole(
controller: DebugConsole.instance,
actions: [],
expandStackTrace: false,
savePath: null,
),
));
}
},
),
)));
});
Get.key.currentState?.overlay?.insert(overlayEntry);
}
DeBug();
}

View File

@ -0,0 +1,92 @@
import 'dart:io';
import 'package:flutter/material.dart';
class DebugConsoleLog {
/// Message of the log.
final String message;
/// Log level, used to determine the color and importance of the log.
final DebugConsoleLevel level;
/// Time of when the log was created.
final DateTime timestamp;
final StackTrace? stackTrace;
DebugConsoleLog({
Object? message,
this.level = DebugConsoleLevel.normal,
DateTime? timestamp,
this.stackTrace,
}) : message = '$message',
timestamp = timestamp ?? DateTime.now();
@override
String toString() {
return '[$level] $timestamp\n$message\n---${stackTrace != null ? ':' : ''}\n${stackTrace != null ? '${stackTrace ?? ''}---\n' : ''}';
}
static List<DebugConsoleLog> fromFile(String filePath) {
final List<DebugConsoleLog> logs = [];
final File file = File(filePath);
if (!file.existsSync()) return logs;
final RegExp regex = RegExp(
r'\[(?<level>.*)\] (?<timestamp>.*)\n(?<message>(?:.|\n)*?)\n---(?::\n(?<stackTrace>(?:.|\n)*?)---\n)?',
multiLine: true,
);
final matches = regex.allMatches(file.readAsStringSync());
for (final match in matches) {
final String level = match.namedGroup('level') ?? 'normal';
final String timestamp = match.namedGroup('timestamp') ?? '';
final String message = match.namedGroup('message') ?? '';
final String stackTrace = match.namedGroup('stackTrace') ?? '';
logs.add(DebugConsoleLog(
message: message,
level: DebugConsoleLevel.values.firstWhere(
(DebugConsoleLevel findingLevel) =>
level.toString() == findingLevel.toString(),
orElse: () => DebugConsoleLevel.normal,
),
timestamp: DateTime.parse(timestamp),
stackTrace:
stackTrace.isNotEmpty ? StackTrace.fromString(stackTrace) : null,
));
}
return logs;
}
}
class DebugConsoleLevel {
static const DebugConsoleLevel normal = DebugConsoleLevel('Normal');
static const DebugConsoleLevel info =
DebugConsoleLevel('Info', Colors.lightBlueAccent);
static const DebugConsoleLevel warning =
DebugConsoleLevel('Warning', Colors.deepOrange);
static const DebugConsoleLevel error =
DebugConsoleLevel('Error', Colors.redAccent);
static const DebugConsoleLevel fatal = DebugConsoleLevel('Fatal', Colors.red);
static const DebugConsoleLevel debug =
DebugConsoleLevel('Debug', Colors.blue);
static const List<DebugConsoleLevel> values = [
normal,
info,
warning,
error,
fatal,
debug,
];
final String name;
final Color? color;
const DebugConsoleLevel(this.name, [this.color]);
@override
String toString() => name;
}

View File

@ -0,0 +1,81 @@
import 'package:flutter/material.dart';
import 'package:star_lock/debug/controller.dart';
import 'package:star_lock/debug/debug_console.dart';
/// A widget that adds a floating button for debugging purposes.
class DebugConsolePopup extends StatefulWidget {
final Widget child;
final bool showButton;
final DebugConsoleController controller;
final List<PopupMenuItem<void>> actions;
final bool expandStackTrace;
final String? savePath;
DebugConsolePopup({
key,
required this.child,
this.showButton = true,
DebugConsoleController? controller,
this.actions = const [],
this.expandStackTrace = false,
this.savePath,
}) :
controller = controller ?? DebugConsole.instance;
@override
State<DebugConsolePopup> createState() => _DebugConsolePopupState();
}
class _DebugConsolePopupState extends State<DebugConsolePopup> {
bool isOpen = false;
@override
Widget build(BuildContext context) {
return Stack(
children: [
widget.child,
if (widget.showButton)
Positioned(
right: 15,
bottom: 15,
child: FloatingActionButton(
child: const Icon(Icons.bug_report),
onPressed: () => popup(true),
),
),
],
);
}
void popup([ bool? open ]) {
open ??= !isOpen;
if (open == isOpen) return;
if (open) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WillPopScope(
onWillPop: () async {
isOpen = false;
return true;
},
child: DebugConsole(
controller: widget.controller,
actions: widget.actions,
expandStackTrace: widget.expandStackTrace,
savePath: widget.savePath,
),
),
),
);
} else {
Navigator.pop(context);
}
isOpen = open;
}
}

View File

@ -0,0 +1,134 @@
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/debug/debug_tool.dart';
import 'package:star_lock/debug/log.dart';
class DebugConsoleTile extends StatefulWidget {
final DebugConsoleLog log;
final bool expanded;
const DebugConsoleTile(this.log, {key, this.expanded = false});
@override
State<DebugConsoleTile> createState() => _DebugConsoleTileState();
}
class _DebugConsoleTileState extends State<DebugConsoleTile> {
ExpandableController? controller;
@override
void initState() {
super.initState();
controller = ExpandableController(initialExpanded: widget.expanded);
}
@override
Widget build(BuildContext context) {
return Container(
color: widget.log.level.color?.withOpacity(0.05),
child: Container(
color: widget.log.level.color?.withOpacity(0.05),
child: InkWell(
onTap: widget.log.stackTrace != null
? () {
controller!.toggle();
setState(() {});
}
: () async {
DeBug.openInfo = true;
await Get.to(DeBugText(widget.log));
DeBug.openInfo = false;
},
child: ExpandablePanel(
controller: controller,
theme: const ExpandableThemeData(
tapBodyToCollapse: false,
tapHeaderToExpand: false,
hasIcon: false,
),
header: ListTile(
textColor: widget.log.level.color,
title: Text(
widget.log.message,
maxLines: 5,
overflow: TextOverflow.ellipsis,
),
trailing: Column(
children: [
SizedBox(height: widget.log.stackTrace != null ? 4 : 15),
Opacity(
opacity: 0.5,
child: widget.log.timestamp
.difference(DateTime.now())
.inDays >
1
? Text(
'${widget.log.timestamp.toIso8601String().substring(0, 10)} ${widget.log.timestamp.toIso8601String().substring(11, 19)}')
: Text(widget.log.timestamp
.toIso8601String()
.substring(11, 19)),
),
if (widget.log.stackTrace != null)
AnimatedRotation(
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
turns: controller!.expanded ? -0.5 : 0,
child: Icon(Icons.keyboard_arrow_down,
color: widget.log.level.color),
)
],
),
),
collapsed: Container(),
expanded: widget.log.stackTrace != null
? Opacity(
opacity: 0.75,
child: ListTile(
textColor: widget.log.level.color,
title: Text(widget.log.stackTrace.toString()),
),
)
: Container(),
),
),
),
);
}
}
class DeBugText extends StatefulWidget {
final DebugConsoleLog log;
DeBugText(this.log, {key});
@override
State<DeBugText> createState() => _DeBugTextState();
}
class _DeBugTextState extends State<DeBugText> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('详细日志'),
),
body: SafeArea(
child: GestureDetector(
onTap: () {
Clipboard.setData(ClipboardData(text: widget.log.message));
EasyLoading.showToast('已复制到剪切板');
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(18.w),
child: Text(widget.log.message),
)),
),
),
);
}
}

View File

@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
// https://github.com/flutter/flutter/issues/63946#issuecomment-1000442747
// - By: https://github.com/PaulBout1
class AllwaysScrollableFixedPositionScrollPhysics extends ScrollPhysics {
const AllwaysScrollableFixedPositionScrollPhysics({ScrollPhysics? parent})
: super(parent: parent);
@override
AllwaysScrollableFixedPositionScrollPhysics applyTo(ScrollPhysics? ancestor) {
return AllwaysScrollableFixedPositionScrollPhysics(parent: buildParent(ancestor));
}
@override
double adjustPositionForNewDimensions({
required ScrollMetrics oldPosition,
required ScrollMetrics newPosition,
required bool isScrolling,
required double velocity,
}) {
if (newPosition.extentBefore == 0) {
return super.adjustPositionForNewDimensions(
oldPosition: oldPosition,
newPosition: newPosition,
isScrolling: isScrolling,
velocity: velocity,
);
}
return newPosition.maxScrollExtent - oldPosition.extentAfter;
}
@override
bool shouldAcceptUserOffset(ScrollMetrics position) => true;
}

View File

@ -26,6 +26,23 @@ class F {
static String get name => appFlavor?.name ?? '';
static bool get debug {
switch (appFlavor) {
case Flavor.local:
return true;
case Flavor.dev:
return true;
case Flavor.pre:
return true;
case Flavor.sky:
return false;
case Flavor.xhj:
return false;
default:
return false;
}
}
static String get title {
switch (appFlavor) {
case Flavor.local:
@ -85,13 +102,16 @@ class F {
case Flavor.local:
case Flavor.dev:
return const StarLockAMapKey(
androidKey: 'b56b681ee89f4db43a5aa1879ae8cbfe', iosKey: 'bd4496e6598ef49796e3a80715035b4d');
androidKey: 'b56b681ee89f4db43a5aa1879ae8cbfe',
iosKey: 'bd4496e6598ef49796e3a80715035b4d');
case Flavor.pre:
return const StarLockAMapKey(
androidKey: '11d49b3f4fc09c04a02bbb7500925ba2', iosKey: '883a3355d2d77c2fdc2667030dc97ffe');
androidKey: '11d49b3f4fc09c04a02bbb7500925ba2',
iosKey: '883a3355d2d77c2fdc2667030dc97ffe');
case Flavor.sky:
return const StarLockAMapKey(
androidKey: 'fb0d2a3e4208b36452cf636aa025a24f', iosKey: '86ca725a12a629c280e116a317aaba19');
androidKey: 'fb0d2a3e4208b36452cf636aa025a24f',
iosKey: '86ca725a12a629c280e116a317aaba19');
// case Flavor.xhj:
// return const StarLockAMapKey(
// androidKey: 'todo',

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:star_lock/debug/debug_console.dart';
import 'package:star_lock/flavors.dart';
import 'package:star_lock/translations/trans_lib.dart';
import 'app.dart';
@ -17,7 +18,13 @@ FutureOr<void> main() async {
//
await _initTranslation();
runApp(MyApp());
if(F.debug){
DebugConsole.listen(() {
runApp(const MyApp());
});
}else{
runApp(const MyApp());
}
if (AppPlatform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle =

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:get/get_connect/http/src/request/request.dart';
import 'package:star_lock/debug/log.dart';
FutureOr<Request> requestLogInterceptor(Request request) async {
Get.log(

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:star_lock/login/login/starLock_login_page.dart';
import 'package:star_lock/tools/appFirstEnterHandle.dart';
import 'package:star_lock/debug/debug_tool.dart';
import 'package:star_lock/tools/storage.dart';
import '../main/lockMian/lockMain/lockMain_page.dart';
@ -15,9 +17,11 @@ class StarLockApplication extends StatefulWidget {
class _StarLockApplicationState extends State<StarLockApplication> {
@override
void initState() {
// TODO: implement initState
super.initState();
print("StarLockApplication initState");
WidgetsBinding.instance.addPostFrameCallback((_) {
DeBug.showFloatWidget();
});
}
@override

View File

@ -29,8 +29,11 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# 1.0.24+202404071、打包预发布环境给欧阳测试
# 1.0.25+20240407021、打包预发布环境给欧阳测试
# 1.0.26+20240408打包预发布环境给欧阳测试
# 1.0.27+2024041101打包提审
# 1.0.27+2024041102打包预发布环境给田总测试
version: 1.0.26+20240408
version: 1.0.27+2024041102
environment:
sdk: '>=2.12.0 <3.0.0'
@ -156,8 +159,10 @@ dependencies:
app_settings: ^5.1.1
flutter_local_notifications: ^17.0.0
fluwx: ^4.5.5
system_settings: ^2.0.0
expandable: ^5.0.1
dev_dependencies:
flutter_test:
sdk: flutter