[英]Unhandled exception in FutureBuilder Flutter
我嘗試在flutter
使用FutureBuilder
小部件從網絡獲取一些數據。 為此我使用下面的代碼:
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");
}
}
和:
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()),
);
}
})
現在,如果http響應在第一次返回錯誤,每件事情都好,但點擊Try again
,如果再次出錯,此消息顯示在控制台上:
[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 <...>
當你調用setState
,你將小部件標記為Dirty並且基本上告訴框架重建它,但只有在getWishList
之后( setState
那個)。 由於它是async
方法,因此可以快速啟動並重建窗口小部件。
通過重建窗口小部件,您可以重建FutureBuilder
,嘗試評估其未來。 由於未來是一個函數,它調用它並對getWishList
進行新的調用。
這使得兩次調用相同的方法,因此兩次調用http服務器非常快。 這些調用可能存在沖突,並引發錯誤。
您不應該直接在FutureBuilder
調用Future
,而是使用以前獲得的 Future
。
Future<List<Product>> myFuture;
@override
void initState() {
myFuture = getWishList();
super.initState();
}
Future<List<Product>> getWishList() async {
//Do your stuff
}
然后在你的構建中,將myFuture
設置為FutureBuilder
的未來,並在你的setState
再次設置myFuture
:
FutureBuilder(
future: myFuture,
builder: (BuildContext context, AsyncSnapshot snapshot) {
//...
setState(() {
myFuture = getWishList();
});
//...
}
);
這將使setState
在myFuture
設置一個新的未來,並要求小部件重建自己。 在FutureBuilder
重建時,它會評估myFuture
而不是再次調用http。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.