resumable_downloader
resumable_downloader
is a lightweight yet powerful download manager for Flutter. It supports:
✅ Resumable downloads using HTTP Range
headers
✅ Concurrent and queued download handling
✅ File existence strategies (keepExisting
, resume
, replace
, fail
)
✅ Download progress updates and cancelation support
✅ Full control using Dio
, custom directory setup, and retry handling
Built for flexibility, designed for scalability.
Features
-
Concurrent Downloading
Support for downloading multiple files at once with efficient management of concurrent tasks. -
Resumable Downloads
Built-in support for resuming interrupted downloads, allowing downloads to continue from where they left off rather than starting over. -
Download Progress Reporting
Track and report download progress with real-time updates via a progress stream. The stream emits progress values between 0.0 (0%) and 1.0 (100%). -
File Existence Handling
Configurable strategies for handling existing files (e.g., skip, overwrite, or resume from the last known state). -
Flexible Logging
Optionally capture and log detailed information about each download, including errors and progress, with customizable log levels (e.g., info, warning, error). -
Customizable Retry Logic
Automatically retries failed downloads based on configurable retry parameters such as maximum retries and delay between attempts. -
Cancel Downloads
Easy cancellation of ongoing downloads, giving full control to the user. -
Optional Callback for Progress
Provides an optional callback function that allows users to track the download progress for each file in the queue. -
Cross-Platform Support
Works seamlessly across all platforms supported by Dart/Flutter, including mobile and desktop applications. -
Optimized for Performance
Efficiently handles multiple concurrent downloads while minimizing memory and CPU usage.
Getting started
To get started with the resumable_downloader
package, follow these steps:
Prerequisites
- Dart 2.12 or later is required. Ensure you have the latest version of Dart installed on your system.
- Flutter (optional, but supported).
- Internet access to download files.
Installation
To install the package, add the following to your pubspec.yaml
file:
dependencies:
resumable_downloader: <latest>
Then, run the following command in your project directory to fetch the package:
flutter pub get
Usage
- Import the package in your Dart code:
import 'package:resumable_downloader/resumable_downloader.dart';
- Create an instance of DownloadManager:
final DownloadManager _downloadManager = DownloadManager(
subDir: AppDefaults.downloadSubDir,
fileExistsStrategy: FileExistsStrategy.resume, // optional
baseDirectory: await getApplicationDocumentsDirectory(), // optional
maxConcurrentDownloads: 3, // optional
maxRetries: 3, // optional
delayBetweenRetries: Duration.zero, // optional
logger: (logRecord) { // optional
logger.log(switch (logRecord.level) {
LogLevel.debug => Level.debug,
LogLevel.error => Level.error,
LogLevel.warning => Level.warning,
LogLevel.info => Level.info,
// ignore: require_trailing_commas
}, 'Download: ${logRecord.message}');
},
);
- Call the getFile, addToQueue, addAllToQueue method with the URL of the file you want to download and optional callbacks to handle progress and completion:
// Download immediately or enqueue with callback
_downloadManager.getFile(
QueueItem(
url: 'https://example.com/file.zip',
fileName: 'download_file.zip', // optional
progressCallback: (progressStream) {
progressStream.listen((progress) {
print('Download progress: ${(progress.progress * 100).toStringAsFixed(1)}%');
});
},
),
);
// Add one item to the queue
_downloadManager.addToQueue(
QueueItem(
url: 'https://example.com/another_file.zip',
fileName: 'download_another_file.zip', // optional
progressCallback: (progressStream) {
progressStream.listen((progress) {
print('Queued file progress: ${(progress.progress * 100).toStringAsFixed(1)}%');
});
},
),
);
// Add multiple items to the queue
_downloadManager.addAllToQueue([
QueueItem(
url: 'https://example.com/file1.zip',
fileName: 'download_file1.zip', // optional
progressCallback: (stream) {
stream.listen((progress) {
print('File 1 progress: ${(progress.progress * 100).toStringAsFixed(1)}%');
});
},
),
QueueItem(
url: 'https://example.com/file2.zip',
fileName: 'download_file2.zip', // optional
progressCallback: (stream) {
stream.listen((progress) {
print('File 2 progress: ${(progress.progress * 100).toStringAsFixed(1)}%');
});
},
),
]);
- Make sure to dispose it
_downloadManager.dispose();
Additional information
This is a straightforward, practical guide for users to get started with the package.
Troubleshooting
- Ensure the download URL is valid and supports Range headers.
- Progress won’t emit unless the server provides a valid Content-Length.
- Check logs for any errors using your provided logger.