|
import 'dart:async'; |
|
import 'dart:developer' show log; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
/// Entry point |
|
void main() => runZonedGuarded<void>( |
|
() { |
|
// Run app |
|
runApp(const App()); |
|
|
|
// Catch flutter errors |
|
final sourceFlutterError = FlutterError.onError; |
|
FlutterError.onError = (details) { |
|
sourceFlutterError?.call(details); |
|
}; |
|
|
|
// Callback after run app |
|
onRun(); |
|
}, |
|
(error, stackTrace) => log('TOP LEVEL ERROR: $error'), |
|
// Inject value into zone |
|
zoneValues: <Symbol, String>{ |
|
_textKey: 'Hello, World!', |
|
}, |
|
); |
|
|
|
/// Callback on run |
|
void onRun() => log( |
|
(StringBuffer() |
|
..writeln('App is running') |
|
..writeln('Text: ${_getTextFromZone()}')) |
|
.toString(), |
|
); |
|
|
|
/// Key for value in zone |
|
const Symbol _textKey = #textKey; |
|
|
|
/// Search value in zone |
|
String _getTextFromZone() { |
|
final buffer = StringBuffer() |
|
..writeln('_getTextFromZone()') |
|
..writeln('Current stackTrace:') |
|
..writeln(StackTrace.current.toString()); |
|
var result = 'Text not found'; |
|
Zone? zone = Zone.current; |
|
while (zone != null) { |
|
final Object? text = zone[_textKey]; |
|
if (text is String) { |
|
buffer.writeln('Result: ${result = text}'); |
|
break; |
|
} else { |
|
buffer.writeln('Zone without key: $zone'); |
|
} |
|
zone = zone.parent; |
|
} |
|
log(buffer.toString()); |
|
return result; |
|
} |
|
|
|
/// App |
|
class App extends StatelessWidget { |
|
const App({Key? key}) : super(key: key); |
|
|
|
@override |
|
Widget build(BuildContext context) => const MaterialApp( |
|
home: Home(), |
|
); |
|
} |
|
|
|
/// Home |
|
class Home extends StatelessWidget { |
|
const Home({Key? key}) : super(key: key); |
|
|
|
@override |
|
Widget build(BuildContext context) => Scaffold( |
|
body: SafeArea( |
|
child: Center( |
|
child: Text( |
|
_getTextFromZone(), |
|
style: const TextStyle(fontSize: 30), |
|
), |
|
), |
|
), |
|
); |
|
} |