How do I cancel Future.delayed?
Asked Answered
O

2

62

How can I cancel/stop a Future.delayed? I read this other question: how can i cancel Future.delayed function calling and someone answered with this possible solution: https://dart.academy/how_cancel_future/, but I don't know how to use it in my code, I don't have a List of Data like the example, I just don't want the code inside the Future.delayed be executed in certain case.

await Future.delayed(Duration(seconds: myDuration)).then((_){

  checkAnswer("");
  jumpToNextQuestion();

});
Orb answered 13/5, 2019 at 21:11 Comment(2)
Do you try to use a timeout ?Spermary
Possible duplicate of is there any way to cancel a dart Future?Vacua
I
106

Use a Timer.

  Timer t = Timer(Duration(seconds: myDuration), () {
    checkAnswer('');
    jumpToNextQuestion();
  });
  // and later, before the timer goes off...
  t.cancel();
Imperfect answered 13/5, 2019 at 21:31 Comment(2)
Can this Timer t survive the App being killed and restart? How can I have a Timer that can be guaranteed to fire across the App's being killed, and restarted?Somniferous
@YuShen For persistent timers, use an alarm from the Alarm Manager although it is Android only.Malisamalison
M
-1

If you need to call a background function after a duration even if the app is killed, an easy way is to push notification triggers.

1. Silent schedule Notifications

You can use silent push notification from flutter_local_notification with a tag.

// Configuration
final FlutterLocalNotificationsPlugin localNotification = FlutterLocalNotificationsPlugin('app_icon');

 const IOSNotificationDetails iosNotificationDetails =
        IOSNotificationDetails(
      categoryIdentifier: 'plainCategory',
    );

const AndroidNotificationDetails androidPlatformChannelSpecifics =
    AndroidNotificationDetails(
        'background id', 'background channel name',
        channelDescription: 'For background triggers',
        importance: Importance.max,
        priority: Priority.high,
        tag: 'backgroud_functions'
   );
         const notificationDetails = NotificationDetails(
                 android:androidPlatformChannelSpecifics, 
                  ios: iosNotificationDetails,
                  androidAllowWhileIdle: true,
                  uiLocalNotificationDateInterpretation:
                      UILocalNotificationDateInterpretation.absoluteTime
        );


// Initize plugin before runApp

localNotification.initialize(
     initializationSettings,
      onSelectNotification: (String? payload) async {
        // Push notification logic
      },
      backgroundHandler:(NotificationActionDetails details){
      // filter background triggers from push notifications and execute.
      if(details.payload.contains(isBackground)){
          // run Any predefined function with parameters from payload
            runFunctions(details.payload[arg1], details.payload[arg2],) 
       }
      ....
       // your usual push notification logic
      },
    );
);

// Calling and setting schedule function 
await localNotification.zonedSchedule(
   function_id, 
   null, // not title we don't want to show a notification
   null, // not body we don't want to show a notification
   tz.TZDateTime.now(tz.local).add(duration_you_need),   // set time here. 
   notificationDetails,
   payload: {isBackground: true, argument1:'value', arg2: 'value'},
);


// to cancel 

localNotification.cancel(function_id, tag: 'backgroud_functions');
  1. OR Use background fetch Check the documentation for details.
Manson answered 16/2, 2022 at 16:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.