downloadAndCacheFile method
Downloads and caches a file in the local filesystem.
This method creates an isolate to handle file downloading in the background, preventing UI jank. It stores the file in a directory and handles HTTP errors and exceptions gracefully by printing error messages.
No return value. This function operates asynchronously.
Implementation
Future<void> downloadAndCacheFile({
bool runInBackground = true
}) async {
final appDocumentsDirectory = await getApplicationDocumentsDirectory();
final String documentsDirectory = appDocumentsDirectory.path;
final directory = Directory('$documentsDirectory/cached_images');
if (!directory.existsSync()) {
directory.createSync(recursive: true);
}
final filePath = '${directory.path}/$id';
final fileExists = await File(filePath).exists();
if (fileExists) {
await _retrieveAndSetCachedFile();
print('File is already cached: $filePath');
return;
}
final ReceivePort receivePort = ReceivePort();
final Completer<void> completer = Completer<void>();
if(!runInBackground) {
await Isolate.spawn(
_downloadFile,
{
'id': id,
'downloadUrl': path,
'documentsDirectory': documentsDirectory,
'completerSendPort': receivePort.sendPort,
},
onExit: receivePort.sendPort,
);
// Listen for completion signal from the spawned isolate
receivePort.listen((_) {
completer.complete();
receivePort.close(); // Close the receive port after completion
});
// Wait for the isolate to complete before returning
await completer.future;
await _retrieveAndSetCachedFile();
return;
}
Isolate.spawn(
_downloadFile,
{
'id': id,
'downloadUrl': path,
'documentsDirectory': documentsDirectory,
'completerSendPort': receivePort.sendPort,
},
onExit: receivePort.sendPort,
).then((value) => null);
// Listen for completion signal from the spawned isolate
receivePort.listen((_) {
_retrieveAndSetCachedFile().then((value) => null);
receivePort.close(); // Close the receive port after completion
});
}