After switching the application to null safety support, the part of the code that is responsible for unlogging stopped working with an error:
LateInitializationError: Field ‘_keepAliveTimer@44195927’ has not been
initialized.
class _TabPageState extends State<TabPage> with SingleTickerProviderStateMixin {
late TabController tabController;
@override
void initState() {
super.initState();
_startKeepAlive(); // initialization
tabController = TabController(length: 4, vsync: this);
}
...
void _startKeepAlive() {
final observer = _KeepAliveObserver();
// assert(observer._keepAliveTimer == null);
observer._keepAlive(true); // errrrrrror
WidgetsBinding.instance.addObserver(observer);
}
class _KeepAliveObserver extends WidgetsBindingObserver {
final _inactivityTimeout = const Duration(seconds: 30);
late Timer? _keepAliveTimer;
void _keepAlive(bool visible) {
_keepAliveTimer?.cancel();
if (visible) {
_keepAliveTimer = null;
} else {
_keepAliveTimer = Timer(_inactivityTimeout, () {
GetIt.instance<LocalStorageService>().resetPassword();
exit(0);
});
}
}
The location of the error is shown by a comment.
How to fix it?
2
Answers
The conditional member access operator (
?.
) is used to access a member of an instance if it’s not null, and do nothing (and returns null) if the instance is null. It does not prevent error that is caused by late variable not initialized yet.The
late
keyword is used to promise that a variable will already be initialized at the time it’s being used. Since your variable is already nullable, you don’t need to put thelate
keyword.First, in general, you should avoid late vars the more you can. That’s because, they can produce errors with like you have.
Once this said, if you really need to have one, you should protect your late vars with test to ensure they are not null.
And for Timers, you should check if they are running before trying to cancel them.
So your function could be: