Reputation: 1844
I am using workmanager
to compress and upload videos in my app in background. The issue is, I wanted to process to run even when app is minimized. It was easily done using this. But in one phone, the app is crashing/closing/restarting when I minimize my app and open other 3-4 apps. I think the ram is not able to handle that.
So, I thought as my process is in workmanager
, it should continue.
Understand this: I have a list of tasks. And each task have list on my UI. Now, each element of that list is used for uploading videos. I have to show the upload progress for each of them. Like if I am uploading 4-5 videos, I should show progress for each of them correctly.
So, what I did? I created a streamController like this:
final orderedFuturesController = StreamController<Future>();
Future preserveOrder(Future future) {
orderedFuturesController.add(future);
return future;
}
So, whenever I tap on a button on the list, it adds a function call to preserveOrder
function. The I created a listener, inside main
function, before runapp
:
final streamSubscription = orderedFuturesController.stream
.asyncMap((future) async => await future)
.listen((_) {}, cancelOnError: false);
Okay. Now, I am calling preserveOrder like this:
await preserveOrder(uploadVideos(uploadVideoData: tempData));
Inside uploadVideos
, I did this:
Future<void> uploadVideos({UploadVideoData? uploadVideoData}) async {
print("Upload videos called");
await Workmanager().registerOneOffTask(
"${uploadVideoData?.pId}_${uploadVideoData?.groupId}", // Unique task key
"uploadVideos", // Task name
inputData: uploadVideoData?.toJson(),
);
}
And I defined my callbackdispatcher
like this:
@pragma('vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
// Handle background task here
SharedPrefs().init();
print("Background task is running");
if(inputData!=null) {
try {
UploadVideoData? uploadVideoData = UploadVideoData.fromJson(inputData);
print("Inside workmanager for: ${uploadVideoData.name}");
String? compressedPath = await compressVideo(uploadVideoData);
uploadVideoData.mediaPath = compressedPath;
await uploadFiles(uploadVideoData);
} catch (e) {
print("Error in bg task: $e");
}
}
return Future.value(true);
});
}
In my uploadFiles
function, I am using https://pub.dev/packages/files_uploader package to upload my files in background.
Now, to update my UI, I created a provider, in which I made 2 maps to keep track of: which taskId (of file_uploader
task) corresponds to which exact upload. And for each elements in my list, what is the percent of corresponding upload file. Now, as soon as i was calling
await preserveOrder(uploadVideos(uploadVideoData: tempData));
I was adding the corresponding data to my provider maps, and saving them in Shared Preferences. Why? So, if my app crashes/restarts, I can initialize all the data again in my provider, and reflect that to UI.
Oh, and I was updating my ui like this:
final subscription = FlutterUploader().progress.listen((progress) async {
print("Progress is: ${progress.progress}");
List<String>? data =
videoUploadProvider.getCorrespondingUniqueId(progress.taskId);
print("Updating: ${data?[0]} and ${progress.progress}");
videoUploadProvider.updateUploadPercent(
data?[0] ?? '', progress.progress?.toDouble() ?? 0.0);
if(progress.progress==100) {
List<String>? completedData =
videoUploadProvider.getCorrespondingUniqueId(progress.taskId);
if (completedData != null) {
print("completed data is: $completedData");
await whenCompletedUpload(completedData);
}
videoUploadProvider.removeElementFromMap(progress.taskId);
}
});
This is also called before runApp
inside main
function.
The problems are:
workmanager
suddenly stops.And when an upload is completed, I remove that from map and shared prefs
, but sometimes, it is not being deleted.
I just want to uploads videos in a queue, one by one each which should not stop even if the app is crashed/closed and progress should be displayed every time, even after restarting the app. I first tried it using queues and recursive functions, but it was not working. So, I tried this.
Can someone help me with this pleaseeee??? I'm stuck in this for more than 2 weeks and I can't find the solution for this.
Upvotes: 1
Views: 389