首页 > 解决方案 > 一些时间延迟的功能在颤动中分流

问题描述

你好,我在收到短信后尝试运行代码,如果在 60 年代之前没有收到短信,我会显示一个警报对话框。目前我的问题是,当我发送一些短信(大约 20 条)时,我的警报对话框会在按下短信发送按钮后直接显示,而无需等待 60 秒的延迟。

这是我的完整示例:

import 'package:flutter/material.dart';
import 'package:sms/sms.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
 // This widget is the root of your application.
    @override
   Widget build(BuildContext context) {
    return new MaterialApp(
    title: 'Flutter Demo',
    theme: new ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: new SettingsPage()
   );
   }
  }
class SettingsPage extends StatefulWidget {
@override
_SettingsPageState createState() => new _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
  bool visibility_waiting;
  String group_last_sms;
  SmsMessage _lastMessage = new SmsMessage('', '');


  @override
  void initState() {
    super.initState();
    visibility_waiting=false;
    new SmsReceiver().onSmsReceived.listen((SmsMessage msg) { //create an sms listener

      if (msg.address == "your phone number") {  //for the test, I wait to receive my owm message to make action
        setState(() {
         _lastMessage = msg;
      });

        RegExp regExp = new RegExp(  // regexp function to extract particular string in the sms and make an action
      r"(test)",
        );
       var match = regExp.firstMatch(_lastMessage.body); // listen the last sms
       group_last_sms = match.group(1);
       if (group_last_sms=="test"){
         setState(() {
_changed(false, "waiting");  // hide visibility of text and circular progress indicator
visibility_waiting=false;
      });
    }
  }
 });

  }
 Widget build(BuildContext context) {
   return Scaffold(

    body: Stack (


      children: <Widget>[
        _buildWidgetContent(), // widget with my raised button , to send test sms

        visibility_waiting?Positioned( // when i press raised button , I show progres indicator, If "test" sms is received I hide circular progress indicator,

            child: Center(
              child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(Colors.lightBlue),
              ),
            ),


        ): new Container(),


        visibility_waiting? // when i press raised button , I show text, If "test" sms is received I hide text,
        new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Column (
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Container(
                  padding: const EdgeInsets.all(80.0),),
                Text('sending sms, please wait', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w600, fontSize: 18.0,
                )),
              ],
            ),
          ],
        ): new Container(),
      ],
    )
   );
  }

 void _changed(bool visibility, String field) { // function for hide or show circular progress indicator
setState(() {
  if (field == "waiting"){
    visibility_waiting = visibility;
   }
  }
  );
 }

  @override
Widget _buildWidgetContent( ) {

return new Scaffold(
    appBar: new AppBar(
    ),
    body: new Stack(
      children: <Widget>[

        new Center(
           child : new RaisedButton(

                onPressed: ()
            {
              visibility_waiting=true;
              _changed(true, "waiting");
              handleSignIn();

              new SmsSender().sendSms(new SmsMessage(
                  "your phone number","test;" )
              );
            }
            )

        )
      ],
    ));
   }

 Future<Null> handleSignIn() async {

await new Future.delayed(const Duration(seconds:20));{  //wait the sms
  if (  visibility_waiting ==true){  // if sms is not received before 60s  _chargement  is true so I show an error dialog
    setState(() {
      visibility_waiting =false;
      _changed(false, "waiting");
      erreurcommunication();
    }
    );
  }
}
}


  Future<Null>erreurcommunication() async {  // alerte dialog when I have waited more than 60s

  await showDialog<String>(
     context: context,
    barrierDismissible: false,
    child: new AlertDialog(
      title: new Text("Problème de reseau"),
      content: new SingleChildScrollView(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text("veuillez reessayer"),

            new OutlineButton(
                child: new  Text('ok', style: TextStyle(color: Colors.black)),
                onPressed: (){
                  setState(() { {
                    Navigator.pop(context);
                  }
                  }
                  );
                },
                highlightElevation: 4.0,
                borderSide: new BorderSide(width: 3.0, color: Colors.grey.shade300),
                highlightColor  : Colors.white,
                shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0))
            ),
            Container (  padding: const EdgeInsets.all(2.0),),
          ],
        ),
      ),
    )
   );
 }  

}

您可以复制此代码并尝试使用您的电话号码。大约按 20 次后,延迟功能会分流 60 秒的延迟并显示警报对话框。

标签: fluttersmsdelay

解决方案


在此处输入图像描述 我试图隔离更多的问题。我已经删除了短信功能,并添加了一个延迟来模拟短信接收。结果:同样的问题,有时 erreurcommunication() 是在 20 秒延迟之前调用的。

 import 'package:flutter/material.dart';


 void main() => runApp(new MyApp());

  class MyApp extends StatelessWidget {
  // This widget is the root of your application.
   @override
  Widget build(BuildContext context) {
   return new MaterialApp(
    title: 'Flutter Demo',
    theme: new ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: new SettingsPage()
 );
 }
 }
class SettingsPage extends StatefulWidget {
  @override
 _SettingsPageState createState() => new _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
bool visibility_waiting;


@override
void initState() {
super.initState();
visibility_waiting=false;
  }
  Widget build(BuildContext context) {
return Scaffold(

    body: Stack (


       children: <Widget>[
        _buildWidgetContent(), // widget with my raised button , to send test sms

          visibility_waiting?Positioned( // when i press raised button , I show progres indicator, If "test" sms is received I hide circular progress indicator,

            child: Center(
              child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(Colors.lightBlue),
              ),
            ),


        ): new Container(),


        visibility_waiting? // when i press raised button , I show text, If "test" sms is received I hide text,
        new Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Column (
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Container(
                  padding: const EdgeInsets.all(80.0),),
                Text('sending sms, please wait', style: TextStyle(color: Colors.black, fontWeight: FontWeight.w600, fontSize: 18.0,
                )),
              ],
            ),
          ],
        ): new Container(),
      ],
    )
   );
  } 

  void _changed(bool visibility, String field) { // function for hide or show circular progress indicator
setState(() {
  if (field == "waiting"){
    visibility_waiting = visibility;
  }
}
);
 }

 @override
 Widget _buildWidgetContent( ) {

return new Scaffold(
    appBar: new AppBar(
    ),
    body: new Stack(
      children: <Widget>[

        new Center(
           child : new RaisedButton(
                onPressed: ()
            {
              setState(() {
                visibility_waiting=true;
                _changed(true, "waiting");
                handleSignIn1(); //waiting 2s before hide progress indicator 
              });
            }
            )

        )
      ],
    ));
   }
 Future<Null> handleSignIn1() async {

  await new Future.delayed(const Duration(seconds:2));{  //simulate the sms received

  visibility_waiting =false;
  _changed(false, "waiting");
                handleSignIn2(); // waitig 20s before show error dialog. the issue = error dialog is show before 20s 

   }
  }
Future<Null> handleSignIn2() async {

await new Future.delayed(const Duration(seconds:20));{  //wait the sms 20s
  if (  visibility_waiting ==true){  // in this case visibility_waiting is always false before 20s, so erreurcommunication() can't be call. currently some time erreurcommunication() is call directly after press raisedbutton
    setState(() {
      visibility_waiting =false;
      _changed(false, "waiting");
      erreurcommunication();
    }
    );
  }
}
}

 Future<Null>erreurcommunication() async {  // alerte dialog when I have waited more than 60s

await showDialog<String>(
    context: context,
    barrierDismissible: false,
    child: new AlertDialog(
      title: new Text("Problème de reseau"),
      content: new SingleChildScrollView(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text("veuillez reessayer"),

            new OutlineButton(
                child: new  Text('ok', style: TextStyle(color: Colors.black)),
                onPressed: (){
                  setState(() { {
                    Navigator.pop(context);
                  }
                  }
                  );
                },
                highlightElevation: 4.0,
                borderSide: new BorderSide(width: 3.0, color: Colors.grey.shade300),
                highlightColor  : Colors.white,
                shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0))
            ),
            Container (  padding: const EdgeInsets.all(2.0),),
          ],
        ),
      ),
    )
   );
 } 
}

推荐阅读