[英]Unhandled exception in FutureBuilder Flutter
i try to use FutureBuilder
widget in flutter
to get some data from network. 我尝试在flutter
使用FutureBuilder
小部件从网络获取一些数据。 for this i use below code : 为此我使用下面的代码:
Future<List<Product>> getWishList() async {
http.Response response = await http.post(
MY_URL,
headers: {
HttpHeaders.acceptHeader: 'application/json',
HttpHeaders.contentTypeHeader: 'application/json; charset=utf-8'
},
);
if (response.statusCode == 200) {
List<Product> ret = List();
Map<String, dynamic> result;
try {
result = json.decode(response.body);
for (var i = 0; i < result['data'].length; i++) {
ret.add(Product.fromJson(result['data'][i]));
}
return ret;
} catch (e) {
return throw Exception("Json parse error");
}
} else {
return throw Exception("network connection failed");
}
}
AND: 和:
FutureBuilder(
future: getWishList(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if(snapshot.connectionState == ConnectionState.done){
if(snapshot.hasError){
controller.forward(from: 0.0);
return Material(
child: Container(
margin: const EdgeInsets.only(top: 36.0),
width: double.infinity,
child: FadeTransition(
opacity: animation,
child: PButton(
onPressed: (){
setState(() {
getWishList();
});
},
child: Column(
children: <Widget>[
Icon(Icons.perm_scan_wifi,color: Colors.black,size: 76.0,),
SizedBox(height:24.0),
Text("Try again",style: TextStyle(fontSize: 16.0,color: const Color(0XFF222222)),),
],
),
),
),
),
);
}else{
return new ListView(
children: <Widget>[
GestureDetector(
onTap:(){
setState(() {
getWishList();
});
},
child: new Text("Every thing ok"))
]);
}
}else{
return Center(
child: Container(
margin: const EdgeInsets.only(top: 36.0),
child: CircularProgressIndicator()),
);
}
})
now if http response return error in first time every thing good but with click on Try again
and if error again this message display on console: 现在,如果http响应在第一次返回错误,每件事情都好,但点击Try again
,如果再次出错,此消息显示在控制台上:
[VERBOSE-2:shell.cc(184)] Dart Error: Unhandled exception: Exception: network connection failed _WishListState.getWishList (package:parchino/screen/screen_wish_list.dart:127:14) _WishListState.build... (package:parchino/screen/screen_wish_list.dart:65:33) State.setState (package:flutter/src/widgets/framework.dart:1130:30) _WishListState.build.. (package:parchino/screen/screen_wish_list.dart:64:31) GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24) TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9) TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:175:7) PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:315:9) PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart<…> [VERBOSE-2:shell.cc(184)] Dart错误:未处理的异常:异常:网络连接失败_WishListState.getWishList(包:parchino / screen / screen_wish_list.dart:127:14)_WishListState.build ...(包: parchino / screen / screen_wish_list.dart:65:33)State.setState(package:flutter / src / widgets / framework.dart:1130:30)_WishListState.build ..(package:parchino / screen / screen_wish_list.dart:64: 31)GestureRecognizer.invokeCallback(包:flutter / src / gestures / recognizer.dart:102:24)TapGestureRecognizer._checkUp(包:flutter / src / gestures / tap.dart:242:9)TapGestureRecognizer.handlePrimaryPointer(包:flutter / src / gestures / tap.dart:175:7)PrimaryPointerGestureRecognizer.handleEvent(package:flutter / src / gestures / recognizer.dart:315:9)PointerRouter._dispatch(package:flutter / src / gestures / pointer_router.dart <...>
When you call setState
, you mark the widget as Dirty and basically tells the framework to rebuild it but only after getWishList
has been called (the one inside setState
). 当你调用setState
,你将小部件标记为Dirty并且基本上告诉框架重建它,但只有在getWishList
之后( setState
那个)。 As it is an async
method, it launches quickly and rebuild the widget. 由于它是async
方法,因此可以快速启动并重建窗口小部件。
By rebuilding the widget, you rebuild the FutureBuilder
which tries to evaluate its future. 通过重建窗口小部件,您可以重建FutureBuilder
,尝试评估其未来。 As the future is a function, it calls it and makes a new call to getWishList
. 由于未来是一个函数,它调用它并对getWishList
进行新的调用。
That makes two calls to the same method and thus two calls to an http server very quickly. 这使得两次调用相同的方法,因此两次调用http服务器非常快。 Those calls are probably in conflict, and throws an error. 这些调用可能存在冲突,并引发错误。
You should not invoke a Future
directly in the FutureBuilder
but use a previously-obtained Future
instead. 您不应该直接在FutureBuilder
调用Future
,而是使用以前获得的 Future
。
Future<List<Product>> myFuture;
@override
void initState() {
myFuture = getWishList();
super.initState();
}
Future<List<Product>> getWishList() async {
//Do your stuff
}
Then in your build, set myFuture
as the future of the FutureBuilder
and in your setState
, set myFuture
again: 然后在你的构建中,将myFuture
设置为FutureBuilder
的未来,并在你的setState
再次设置myFuture
:
FutureBuilder(
future: myFuture,
builder: (BuildContext context, AsyncSnapshot snapshot) {
//...
setState(() {
myFuture = getWishList();
});
//...
}
);
That will make the setState
set a new future in myFuture
and ask the widget to rebuilt itself. 这将使setState
在myFuture
设置一个新的未来,并要求小部件重建自己。 As the FutureBuilder
rebuild, it evaluates myFuture
instead of calling http once again. 在FutureBuilder
重建时,它会评估myFuture
而不是再次调用http。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.