gpt4 book ai didi

flutter - 如何从Flutter中的异步函数安全地调用setState函数?

转载 作者:行者123 更新时间:2023-12-03 04:27:05 25 4
gpt4 key购买 nike

我的flutter应用程序中有一个下载按钮,在文件下载时按下Text("download")之前将显示CircularProgressIndicator(),在文件下载时按下Text("Open")

_FileStatus status = _FileStatus.EMPTY;

RaisedButton raisedButton() {
var child;
if (status == _FileStatus.EMPTY) {
child = Text("download");
} else if (status == _FileStatus.DOWNLOADING) {
child = CircularProgressIndicator();
} else {
child = Text("Open");
}
return RaisedButton(
child: child,
onPressed: () {
if (status == _FileStatus.EMPTY) {
setState(() {
status = _FileStatus.DOWNLOADING;
});
download().then((bool isDownloaded) {
if (isDownloaded) {
//setState status=>Downloaded
} else {
//setState status=>Empty
}
});
} else {
print("Open");
}
},
);
}

Future<bool> download() async {
var response = await Future<bool>.delayed(Duration(seconds: 5), () {
print("Downloading ...");
return true;
});
if (response) {
print("Downloaded");
return true;
} else {
print("Download Failed!");
return false;
}
}

但是此按钮位于应用程序的第二页。因此,可以按下下载按钮,然后返回首页。通常,如果我按下下载按钮,然后等待它完成,则setState会将 status更新为 DOWNLOADED;没问题。但是,如果我按 download按钮然后返回,则 download()将在后台运行,当它完成时,它将尝试运行我已注释掉的 setState方法之一。这要么给出错误,要么说内存泄漏问题。

我试图通过使用isLoaded变量解决此问题。
@override
void initState() {
isLoaded = true;
super.initState();
}
@override
void dispose() {
isLoaded = false;
super.dispose();
}

然后在调用setState方法之前检查isLoaded是否为true。
if (isLoaded) {
setState(() {
status = _FileStatus.DOWNLOADING;
});
}

但这感觉像是骇人听闻的方法,我知道必须有更好的方法来解决此问题。我已经搜索了其他类似的问题,但找不到我想要的东西。

最佳答案

只需添加一个条件来检查您的状态是否已挂载,以及何时未挂载-请勿调用setState:

          download().then((bool isDownloaded) {
// Checking if widget is mounted
if (!mounted) {
return;
}

...

关于flutter - 如何从Flutter中的异步函数安全地调用setState函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59014787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com