在第一次出现屏幕时,我要检查是否启用了用户GPS并授予了“位置许可”。然后,如果其中之一没有满足,我会显示对话框以打开应用程序设置。
_initPermission(BuildContext context) async {
final geolocationStatus = await commonF.getGeolocationPermission();
final gpsStatus = await commonF.getGPSService();
if (geolocationStatus != GeolocationStatus.granted) {
showDialog(
context: context,
builder: (ctx) {
return commonF.showPermissionLocation(ctx);
},
);
} else if (!gpsStatus) {
showDialog(
context: context,
builder: (ctx) {
return commonF.showPermissionGPS(ctx);
},
);
}
}
然后我像这样在initState中调用此函数:
void initState() {
super.initState();
Future.delayed(Duration(milliseconds: 50)).then((_) => _initPermission(context));
}
问题是,每当屏幕第一次出现时,都会给我这样的错误:
[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.
我做了什么:
//1
WidgetsBinding.instance.addPostFrameCallback((_) {
_initPermission(context);
});
//2
SchedulerBinding.instance.addPostFrameCallback((_) => _initPermission(context));
//3
Timer.run(() {
_initPermission(context);
})
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Scaffold(
key: _scaffoldKey,
我完成的结果什么都没有,错误仍然出现在第一次屏幕上。
但是奇怪的是,这仅在第一次出现屏幕时发生。当我热重启时,错误消息消失了。
答案 0 :(得分:0)
我无法对其进行测试(我没有GPS软件包),但尝试更改
Future.delayed(Duration(milliseconds: 50)).then((_) => _initPermission(context));
到
Future.delayed(Duration(milliseconds: 50)).then((_) => _initPermission()); //this inside the initstate
_initPermission() async{
final geolocationStatus = await commonF.getGeolocationPermission();
final gpsStatus = await commonF.getGPSService();
if (geolocationStatus != GeolocationStatus.granted) {
await showDialog(
context: context,
builder: (ctx) => commonF.showPermissionLocation
},
);
} else if (!gpsStatus) {
await showDialog(
context: context,
builder: (ctx) => commonF.showPermissionGPS
},
);
}
} // the stateful widget can use the context in all its methods without passing it as a parameter
该错误在热重启中消失了,因为它只是刷新了小部件的状态,但是它已经创建了(如果您进行热重启并在initState内进行打印,例如print('This is init');,则不会之所以看到它,是因为刷新不会处理并初始化小部件,因此不会再次运行该代码段
编辑
基于您的要点,我只是制作了一个可重现的示例,并且在DartPad中运行没有问题,稍后我将在VS上尝试它,但是现在您可以检查是否有其他区别
enum GeolocationStatus{granted, denied} //this is just for example
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
showPermissionGPS() {
return AlertDialog(
title: Text('GPSStatus'),
);
}
_showPermissionLocation() {
return AlertDialog(
title: Text('Permission Localization'),
);
}
@override
initState(){
super.initState();
Future.delayed(Duration(milliseconds: 50)).then((_) => _initPermission());
}
_initPermission() async{
final geolocationStatus = await Future<GeolocationStatus>.value(GeolocationStatus.granted); //mocked future with a response to test
final gpsStatus = await Future<bool>.value(false); //mocked future with a response to test
if (geolocationStatus != GeolocationStatus.granted) {
await showDialog(
context: context,
builder: (ctx) => _showPermissionLocation() //this mock commonF.showPermissionLocation and returns an AlertDialog
);
} else if (!gpsStatus) {
await showDialog(
context: context,
builder: (ctx) => _showPermissionGPS() //this mock commonF.showPermissionGPS and returns an AlertDialog
);
}
}
@override
Widget build(BuildContext context) {
return Text('My text');
}
}