Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation - How to communicate between the background task (isolate) and other widgets #541

Open
4 tasks done
jonathanMNg opened this issue Mar 2, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@jonathanMNg
Copy link

  • I have read the README
  • I have done the setup for Android
  • I have done the setup for iOS
  • I have ran the sample app and it does not work there

Version
0.5.0

Describe the error
Hi,
I'm trying to execute a Bloc event with the workmanager callbackDispatcher().
However, because the function callbackDispatcher itself is an Isolate, it can't modify the variables of the main execution. My workaround is to use SendPort and ReceivePort.

In the main.dart:

@pragma('vm:entry-point')
void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) {
    if(task == 'sleep-timer') {
      final SendPort? send = IsolateNameServer.lookupPortByName('sleep_timer_send_port');
      if (send != null) {
        send.send(inputData);
      }
    }
    return Future.value(true);
  });
}

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Workmanager().initialize(callbackDispatcher,isInDebugMode: true);
  runApp(const MyApp());
}

In the timer_bloc.dart:


 TimerBloc() : super(TimerInitial()) {

    on<Start>((event, emit) async {
      Workmanager().cancelByTag('sleep-timer-tag');
      final ReceivePort port = ReceivePort();
      _bindBackgroundIsolate(port);
      await Workmanager().registerOneOffTask(
          UniqueKey().toString(),
          'sleep-timer',
          tag: 'sleep-timer-tag',
          initialDelay: event.duration,
          inputData: {"executeTask": true},
          existingWorkPolicy: ExistingWorkPolicy.replace
      );
  });

  void _bindBackgroundIsolate(ReceivePort port) {
    final isSuccess = IsolateNameServer.registerPortWithName(port.sendPort, 'sleep_timer_send_port');
    if (!isSuccess) {
      _unbindBackgroundIsolate('sleep_timer_send_port');
      _bindBackgroundIsolate(port);
      return;
    }
    port.listen((dynamic data) async {
      // final isDone = data;
      if(data != null && data['executeTask']) {
        do_other_task();
      }
    });
  }
  void _unbindBackgroundIsolate(String name) {
    IsolateNameServer.removePortNameMapping(name);
  }
}

I think that adding this to the documentation would help others. FYI, I copied that code from this project flutter_downloader
Thanks,

@jonathanMNg jonathanMNg added the bug Something isn't working label Mar 2, 2024
@SEGVeenstra
Copy link

I can imagine this being a very common use-case when using background tasks.
At least I found out I needed this within the first week of using background tasks.

Not sure if the documentation would require a full guide or maybe just a section with some references to this issue for example, as this is more about how Isolates work then about this package specifically.

Anyway, I'm very grateful that you shared this!

@aap01
Copy link

aap01 commented Sep 6, 2024

@jonathanMNg
Thanks!
Very resourceful. Had I found this in the documentation, I would have saved 4 hours of my day.

@PsyOhm23
Copy link

PsyOhm23 commented Oct 8, 2024

Thank you but unfortunately this solution don't work after killing the app or restarting the device :(

@jonathanMNg
Copy link
Author

Thank you but unfortunately this solution don't work after killing the app or restarting the device :(

Yes, there is no way to do it in IOS, and you maybe able to do it in Android if you can fork the Android kernel and modify it to add your app to run after killing/restarting :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants