flutter_workmanager
flutter_workmanager copied to clipboard
🐞[Android][Handling cancellation of running work]
- [x] I have read the README
- [x] I have done the setup for Android
- [x] I have done the setup for iOS
- [x] I have ran the sample app and it does not work there
Version workmanager: 0.5.0
Describe the error
When a task is cancelled by WorkManager, there is no way to intercept the cancellation.
Steps to reproduce
- Start a one off task with a network constraint
Workmanager().registerOneOffTask(
'taskUniqueName-${DateTime.now().millisecondsSinceEpoch}',
'someTaskName',
constraints: Constraints(networkType: NetworkType.connected),
outOfQuotaPolicy: null,
);
- while the task is running, disconnect from the internet
- the task is cancelled
I/WM-WorkerWrapper(12832): Work [ id=ab6c64e1-f244-44ff-8790-b2f79aafd52a, tags={ be.tramckrijte.workmanager.BackgroundWorker } ] was cancelled
I/WM-WorkerWrapper(12832): java.util.concurrent.CancellationException: Task was cancelled.
I/WM-WorkerWrapper(12832): at androidx.work.impl.utils.futures.AbstractFuture.cancellationExceptionWithCause(AbstractFuture.java:1184)
I/WM-WorkerWrapper(12832): at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:514)
I/WM-WorkerWrapper(12832): at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
I/WM-WorkerWrapper(12832): at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:311)
I/WM-WorkerWrapper(12832): at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
I/WM-WorkerWrapper(12832): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
I/WM-WorkerWrapper(12832): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
I/WM-WorkerWrapper(12832): at java.lang.Thread.run(Thread.java:919)
Proposal
The plugin should expose a stream of cancellation events for the scheduled tasks.
There could be an EventSink on the native side that gets its events from invoking
https://developer.android.com/topic/libraries/architecture/workmanager/how-to/managing-work#onstopped_callback
in the worker implementation. The event should have enough information so that a developer can know which task was cancelled. Thus an event would at least need the unique name (and the original input data?)
Output of flutter doctor -v
[✓] Flutter (Channel stable, 3.3.2, on macOS 12.2.1 21D62 darwin-x64, locale
en-BE)
• Flutter version 3.3.2 on channel stable at
/Users/navaronbracke/Documents/flutter
• Upstream repository [email protected]:flutter/flutter.git
• Framework revision e3c29ec00c (3 weeks ago), 2022-09-14 08:46:55 -0500
• Engine revision a4ff2c53d8
• Dart version 2.18.1
• DevTools version 2.15.0
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
• Android SDK at /Users/navaronbracke/Library/Android/sdk
• Platform android-33, build-tools 33.0.0
• ANDROID_HOME = /Users/navaronbracke/Library/Android/sdk
• Java binary at: /Applications/Android
Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build
11.0.12+0-b1504.28-7817840)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 13F100
• CocoaPods version 1.11.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2021.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build
11.0.12+0-b1504.28-7817840)
[✓] VS Code (version 1.71.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.48.0
[✓] Connected device (2 available)
• macOS (desktop) • macos • darwin-x64 • macOS 12.2.1 21D62 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 105.0.5195.125
[✓] HTTP Host Availability
• All required HTTP hosts are available
• No issues found!
This is a great idea.
Why would you want to intercept - e.g. what would you like to do as a developer with the information? Reschedule another task?
Well, I had a task indicator that would show progress (pending, running, done) and I was looking for a way to indicate a cancelled state.
So your use case is just to show when things have failed. How would you handle the case when the task runs in the background but your main application is not visible?
In my use case, I let the background task write the progress information to a database (which uses dart:ffi since it needs to be accessible across both the foreground Flutter Engine & the background Flutter Engine, which don't live in the same engine group). I don't show any updates when the app is in the background. When the application is in the foreground, I just observe the database for updates.