【问题标题】:FlutterError (setState() called after dispose(): (lifecycle state: defunct, not mounted)FlutterError (setState() 在 dispose() 之后调用:(生命周期状态:已失效,未挂载)
【发布时间】:2020-12-14 23:22:12
【问题描述】:

错误在两个区域引发(并且应用程序冻结(当应用程序被最小化时,当点击手机后退按钮时,或者当另一个应用程序在颤振应用程序之上运行时)颤振版本:1.20.2(以前的版本没有这个问题):这两个功能是:

@override
void initState() {
super.initState();
getItems();
} 

getItems() async {
 initClearVisibility();
 initFilters();
 setState(() {
 loadingItems = true;
 Visibility(visible: true, child: CircularProgressIndicator());
 });

QuerySnapshot querySnapshot = await query.get();
 items = querySnapshot.docs;
 lastDocument = querySnapshot.docs[querySnapshot.docs.length - 1];
 setState(() {
 loadingItems = false;
 Visibility(visible: false, child: CircularProgressIndicator());
 });
}

initClearVisibility() {
 if (Str.filterSelectCategory != Str.CATEGORY) {
  clearCategoryVisible = true;
  allCategoriesVisible = false;
   categoryValue = Str.filterSelectCategory;
  setState(() {});
 }
}

initFilters() async {   
 filterDefaultItems();
}

filterDefaultItems() async {
  query = _firestore
  .collection(Str.ITEMS)
  .where(Str.IS_ITEM_SOLD, isEqualTo: false) 
  .where(Str.ADDRESS, isEqualTo: userAddress1)
  //.orderBy(Str.DATE_POSTED)
  .limit(perPage);
}

第二个区域在我也得到的以下代码上::

class FABBottomAppBarItem {
FABBottomAppBarItem({this.iconData, this.itemColor}); //, this.text});
IconData iconData;
var itemColor;
//String text;
}

class FABBottomAppBar extends StatefulWidget {
 FABBottomAppBar({
 this.items,
 this.centerItemText,
 this.height: 65.0,
 this.iconSize: 24.0,
 this.backgroundColor,
 this.color,
 this.selectedColor,
 this.notchedShape,
 this.onTabSelected,
 }) {
 assert(this.items.length == 2 || this.items.length == 4);
}
final List<FABBottomAppBarItem> items;
final String centerItemText;
final double height;
final double iconSize;
final Color backgroundColor;
final Color color;
final Color selectedColor;
final NotchedShape notchedShape;
final ValueChanged<int> onTabSelected;

@override
State<StatefulWidget> createState() => FABBottomAppBarState();
}

class FABBottomAppBarState extends State<FABBottomAppBar> {
//int _selectedIndex = 0;
int unreadCount = 0;

_updateIndex(int index) {
 widget.onTabSelected(index);
 setState(() {
  //_selectedIndex = index;
  });
}

@override
void initState() {
 super.initState();
 countDocuments();
}

@override
Widget build(BuildContext context) {
List<Widget> items = List.generate(widget.items.length, (int index) {
  return _buildTabItem(
    item: widget.items[index],
    index: index,
    onPressed: _updateIndex,
  );
});
items.insert(items.length >> 1, _buildMiddleTabItem());

return BottomAppBar(
  shape: widget.notchedShape,
  child: Row(
    mainAxisSize: MainAxisSize.max,
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: items,
  ),
  color: widget.backgroundColor,
 );
}

Widget _buildMiddleTabItem() {
 return Expanded(
  child: SizedBox(
    height: MediaQuery.of(context).size.height * 0.075, //widget.height,
    child: Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        SizedBox(
          height: MediaQuery.of(context).size.height * 0.04,
        ), 
        Text(
          widget.centerItemText ?? '',
          style: TextStyle(
              color: BwerereTheme.bwerereRed,
              fontSize: 14.0,
              fontWeight: FontWeight.w900),
        ),
      ],
    ),
  ),
  );
}

Widget _buildTabItem({
 FABBottomAppBarItem item,
 int index,
 ValueChanged<int> onPressed,
 }) 
{
 return Expanded(
  child: SizedBox(
    height: MediaQuery.of(context).size.height * 0.065,
    child: Material(
      type: MaterialType.transparency,
      child: InkWell(
        onTap: () => onPressed(index),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Stack(
              children: <Widget>[
                Icon(item.iconData,
                    color: item.itemColor,
                    size: IconTheme.of(context).size * 1.2),
                index == 2 ? badge() : Container()
              ],
            )
          ],
        ),
      ),
    ),
   ),
   );
  }

  Widget badge() => unreadCount < 1
   ? Container()
    : Container(
      padding: EdgeInsets.all(4.0),
      decoration: BoxDecoration(
          color: BwerereTheme.bwerereRed, shape: BoxShape.circle),
      child: Center(
        child: RobotoFont(
            text: "$unreadCount",
            textSize: 12.0,
            textColor: Colors.white,
            fontWeight: FontWeight.w400),
      ));

 void countDocuments() async {
 final uid = await FetchUserData().getCurrentUserID();
 QuerySnapshot _myDoc = await FirebaseFirestore.instance
    .collection("userUnreadMessages")
    .doc(uid)
    .collection(Str.MESSAGE_COLLECTION)
    .get();
 List<DocumentSnapshot> _myDocCount = _myDoc.docs;
 setState(() {
  unreadCount = _myDocCount.length;
  print('NOTIY LENGTH::: $unreadCount');
 });
}

}

FABBottomAppBarState 的 FRAMEWORK.DART 错误。

在 HomePage() 上的 getItems 上抛出相同的错误

发生了异常。 FlutterError (setState() 在 dispose() 之后调用:FABBottomAppBarState#250ac(生命周期状态:已失效,未安装) 如果您对不再出现在小部件树中的小部件(例如,其父小部件不再在其构建中包含该小部件)调用 State 对象上的 setState(),则会发生此错误。当代码从计时器或动画回调中调用 setState() 时,可能会发生此错误。 首选的解决方案是取消计时器或停止在 dispose() 回调中收听动画。另一种解决方案是在调用 setState() 之前检查该对象的“已安装”属性,以确保该对象仍在树中。 如果 setState() 被调用,则此错误可能表示内存泄漏,因为另一个对象在从树中删除此 State 对象后仍保留对该对象的引用。为避免内存泄漏,请考虑在 dispose() 期间中断对此对象的引用。)

然后进一步调查显示,该应用程序占用了大约 400MB 的手机内存 (Ram),我觉得这太高了。

帮助找出问题真的很有帮助。提前致谢。

附加信息: 在android 7.0上运行时出现错误,flutter 1.20.2。请参阅https://github.com/flutter/flutter/issues/35900 上的类似/相关问题。请注意,我升级到 Flutter 1.20.2 和降级到 1.7.5 将需要我在升级后进行大量更改,尤其是在 Firestore 上(注意:https://firebase.flutter.dev/docs/migration 最近更新了)。

【问题讨论】:

  • 你应该使用if (mounted) setState((){});而不是setState((){});
  • @void - 我已经尝试过了,但它不起作用。
  • 您是否对调用三个setState((){}) 的位置进行了所有更改?
  • @void 谢谢...它工作得很好...卡了几个小时...
  • 谢谢,它帮助了我。

标签: flutter dart


【解决方案1】:

await 之后,您的小部件可能不再安装。那时执行 setState 会给您一个例外。这实际上是一件好事,后面的代码无论如何都不应该执行,因为你在别的地方。

对于“在 dispose() 后调用的 setState()”异常,您有三个选项:

  1. 安全地忽略它。例外情况是使您的函数无法继续。
  2. 在每个awaitsetState() 之间放置一个if (!mounted) return;。将它放在每个await 之后可能是一个好习惯。
  3. 将您的 setState() 调用替换为 setStateIfMounted() 并将其定义为:
void setStateIfMounted(f) {
  if (mounted) setState(f);
}

我在video 中解释了这些方法。

【讨论】:

  • 已经使用了 if (!mounted) 返回;让我测试一下;但随后的错误github.com/flutter/flutter/issues/35900 在单击电话导航时仍然显示以下日志: DequeueBuffer: dequeueBuffer failed and ( 3778): gles_state_set_error_internal:75: [MALI] GLES ctx: 0x88f80008, error code:0x505 - 我不确定是否有错误有关系。我想使用第三个选项,在我的情况下 (f) 代表什么?
  • f 是你给 setState() 的函数。所以,当你做setState(() { a = 1; }); 时,f 是() { a = 1; }。我对其他 DequeueBuffer 异常一无所知。
  • 好的。我还没有收到处理后调用的 onState 错误。我将 gls_state_set_error 作为单独的错误 - 以防万一
  • 好吧,这只是隐藏了错误,因为 setState 没有被调用,而它应该被调用但以延迟的方式调用。
【解决方案2】:

你可以使用:

  if (this.mounted) { // check whether the state object is in tree
    setState(() {
      // make changes here
    });
  }

mounted 检查此State 对象当前是否在tree 中。 mounted class

【讨论】:

    【解决方案3】:

    对于初学者和易于理解的检查bool isMount = true;,当dispose() 将被称为bool isMount = false;setState() 将不会被调用。

    class TotalBooks extends StatefulWidget {
      TotalBooks({Key? key}) : super(key: key);
      // code omitted..
      bool isMount = true;
      @override
      _TotalBooksState createState() => _TotalBooksState();
    }
    
    class _TotalBooksState extends State<TotalBooks> {
      @override
      void initState() {
      // code omitted..
          if (widget.isMount) {
            setState(() {
      // code omitted..
            });
          }
        });
        super.initState();
      }
    
      @override
      void dispose() {
        // TODO: implement dispose
        widget.isMount = false;
      // code omitted..        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return SizedBox();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-28
      • 1970-01-01
      • 2021-03-12
      • 2018-08-26
      • 2018-08-28
      • 2019-10-28
      • 2021-11-25
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多