首页 > 解决方案 > Periodic Timer 无法处理

问题描述

代码内容并不重要。当我想离开这个页面时,只有一个问题计时器无法处理。当我离开此页面时,sendMessage("message");功能继续运行。有没有办法处理这个计时器?

Timer timer;

@override
void initState() {
super.initState();
timer = Timer.periodic(new Duration(seconds: 5), (timer) async {
          setState(() {
            unicode++;
            unicodeString = unicode.toString();
            if (unicodeString.length < 6) {
              int different = 6 - unicodeString.length;
              for (var i = 0; i < different; i++) {
                unicodeString = "0" + unicodeString;
              }
            }
            sendMessage("meesage");
              showSnackBarWithKey("Message Sended !");
          });
    });
}
 @override
 void dispose() {
 timer.cancel();
 super.dispose();
}

错误如下。

小部件库捕获的异常在完成小部件树时引发了以下断言:'package:flutter/src/widgets/framework.dart':断言失败:第 4182 行 pos 12:'_debugLifecycleState != _ElementLifecycle.defunct':不正确. 断言表明框架本身存在错误,或者我们应该在此错误消息中提供更多信息,以帮助您确定和修复根本原因。无论哪种情况,请通过在 GitHub 上提交错误来报告此断言:

我使用了dispose timer,但它不能dispose timer。我无法解决这个问题。请帮忙。

标签: flutterdart

解决方案


我在运行您的代码后发现了问题,主要问题是,当从父树中完全删除小部件时,会在小部件上调用 dispose。

所以当你路由新页面时,

  1. 使用推送导航,在当前屏幕顶部添加一个新屏幕。因此(旧屏幕的)树没有被完全破坏,因此不会调用 dispose。
  2. 使用流行音乐。屏幕被移除,树也被移除。因此调用了 dispose 。
  3. 使用推送替换。新屏幕替换旧屏幕删除小部件树。所以调用了 dispose 。

对于代码,试试这个。(主要部分是pushReplacement我用它来导航)

Navigator.pushReplacement(
               context, MaterialPageRoute(builder: (context) => SplashScreen()));

最终代码是,

 class TimerButton extends StatefulWidget {
      @override
      _TimerButtonState createState() => _TimerButtonState();
    }
    
    class _TimerButtonState extends State<TimerButton> {
      Timer _timer;
      @override
      void initState() {
        super.initState();
    
        _timer = Timer.periodic(new Duration(seconds: 5), (timer)  async{
          setState(() {
           /* unicode++;
            unicodeString = unicode.toString();
            if (unicodeString.length < 6) {
              int different = 6 - unicodeString.length;
              for (var i = 0; i < different; i++) {
                unicodeString = "0" + unicodeString;
              }
            }*/
            sendMessage("meesage");
            showSnackBarWithKey("Message Sended !");
          });
        });
      }
      @override
      void dispose() {
        _timer.cancel();
        super.dispose();
      }
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
       return RaisedButton(
         onPressed: (){
           Navigator.pushReplacement(
               context, MaterialPageRoute(builder: (context) => SplashScreen()));
         },
         child: Text("data"),
       );
      }
    }

推荐阅读