字节笔记本
2026年3月22日
Flutter Downloader - 文件下载管理插件
本文介绍 Flutter Downloader,一个用于创建和管理下载任务的 Flutter 插件,支持在 Android 和 iOS 平台上实现后台文件下载。
项目简介
Flutter Downloader 是由 Flutter Community 维护的一个开源插件,它为 Flutter 应用提供了强大的文件下载管理能力。该插件在 Android 平台使用 WorkManager 实现后台下载任务,在 iOS 平台则使用 NSURLSessionDownloadTask 来完成下载操作。无论应用是否在前台运行,下载任务都能可靠地执行。该项目在 GitHub 上获得了超过 900 个 Star,被超过 10,600 个项目使用,是 Flutter 生态中最受欢迎的下载管理插件之一。
需要注意的是,早期版本存在 SQL 注入漏洞,官方强烈建议升级到最新版本以获得必要的安全修复。同时,Android 11 的外部存储 API 变更也对当前实现产生了一定影响,项目正在进行重新设计以适配新的存储策略。
核心特性
- 跨平台支持:同时支持 Android 和 iOS 平台的后台下载
- 后台下载:应用退出后下载任务仍然可以继续执行
- 任务管理:支持创建、暂停、恢复、取消和重试下载任务
- 进度回调:实时获取下载进度和状态更新
- 并发控制:可配置最大同时下载任务数量(默认为 3)
- 通知栏集成:Android 平台支持在通知栏显示下载进度,点击通知可直接打开已下载文件
- 请求头定制:支持自定义 HTTP 请求头(如身份认证 Token)
- 任务持久化:下载任务信息通过 SQLite 数据库持久化存储
- 本地化支持:支持通知消息的多语言本地化
- HTTP 支持:可配置是否允许非 HTTPS 请求
技术栈
- Dart:Flutter 插件的桥接层实现(21.1%)
- Kotlin:Android 平台原生实现,基于 WorkManager(43.5%)
- Objective-C:iOS 平台原生实现,基于 NSURLSessionDownloadTask(33.6%)
- Swift:iOS 平台的部分支持(0.2%)
- SQLite:下载任务信息的本地持久化存储
- WorkManager:Android 平台的后台任务调度
- NSURLSession:iOS 平台的后台网络请求
安装指南
添加依赖
在 pubspec.yaml 文件中添加以下依赖:
dependencies:
flutter_downloader: ^1.11.8然后运行 flutter pub get 安装依赖。
iOS 平台配置
iOS 平台需要进行以下配置:
-
启用后台模式:在 Xcode 中打开
ios项目,在Signing & Capabilities中启用Background Modes,并勾选Background fetch。 -
添加 sqlite 库:在 Xcode 中依次点击
Build Phases->Link Binary With Libraries,添加libsqlite3.tbd。 -
配置 AppDelegate:
Objective-C 方式:
// AppDelegate.h
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end// AppDelegate.m
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
#include "FlutterDownloaderPlugin.h"
@implementation AppDelegate
void registerPlugins(NSObject<FlutterPluginRegistry>* registry) {
if (![registry hasPlugin:@"FlutterDownloaderPlugin"]) {
[FlutterDownloaderPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterDownloaderPlugin"]];
}
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
[FlutterDownloaderPlugin setPluginRegistrantCallback:registerPlugins];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@endSwift 方式:
import UIKit
import Flutter
import flutter_downloader
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
FlutterDownloaderPlugin.setPluginRegistrantCallback(registerPlugins)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
private func registerPlugins(registry: FlutterPluginRegistry) {
if (!registry.hasPlugin("FlutterDownloaderPlugin")) {
FlutterDownloaderPlugin.register(with: registry.registrar(forPlugin: "FlutterDownloaderPlugin")!)
}
}Android 平台配置
Android 平台开箱即用,无需额外配置。以下为可选配置:
打开已下载文件:在 AndroidManifest.xml 中添加 FileProvider:
<provider
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
android:authorities="${applicationId}.flutter_downloader.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>快速开始
初始化插件
在使用任何下载功能之前,必须在 main() 函数中初始化插件:
import 'package:flutter_downloader/flutter_downloader.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
debug: true, // 可选:设置为 false 禁用控制台日志输出(默认为 true)
ignoreSsl: true // 可选:设置为 false 禁用 HTTP 链接(默认为 false)
);
runApp(MyApp());
}使用示例
创建下载任务
使用 enqueue 方法创建一个新的下载任务:
final taskId = await FlutterDownloader.enqueue(
url: 'https://example.com/file.pdf',
headers: {'Authorization': 'Bearer your_token'}, // 可选:自定义请求头
savedDir: '/path/to/save/directory', // 文件保存目录
showNotification: true, // 在状态栏显示下载进度(Android)
openFileFromNotification: true, // 点击通知打开已下载文件(Android)
);监听下载进度
下载回调函数运行在后台 Isolate 中,需要通过 ReceivePort 与 UI 线程通信:
ReceivePort _port = ReceivePort();
@override
void initState() {
super.initState();
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen((dynamic data) {
String id = data[0];
DownloadTaskStatus status = DownloadTaskStatus(data[1]);
int progress = data[2];
// 更新 UI
setState(() { });
});
FlutterDownloader.registerCallback(downloadCallback);
}
@override
void dispose() {
IsolateNameServer.removePortNameMapping('downloader_send_port');
super.dispose();
}
@pragma('vm:entry-point')
static void downloadCallback(String id, int status, int progress) {
final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id, status, progress]);
}注意:
@pragma('vm:entry-point')注解必须添加在回调函数上方,以避免 Android release 模式下的 tree shaking 优化。
加载所有任务
final tasks = await FlutterDownloader.loadTasks();使用 SQL 查询加载任务
final tasks = await FlutterDownloader.loadTasksWithRawQuery(
query: 'SELECT * FROM task WHERE status=3',
);任务控制
// 取消指定任务
FlutterDownloader.cancel(taskId: taskId);
// 取消所有任务
FlutterDownloader.cancelAll();
// 暂停任务
FlutterDownloader.pause(taskId: taskId);
// 恢复任务(返回新的 taskId)
final newTaskId = await FlutterDownloader.resume(taskId: taskId);
// 重试失败的任务(返回新的 taskId)
final newTaskId = await FlutterDownloader.retry(taskId: taskId);
// 删除任务
FlutterDownloader.remove(taskId: taskId, shouldDeleteContent: false);
// 打开已下载的文件
FlutterDownloader.open(taskId: taskId);配置最大并发任务数
iOS:在 Info.plist 中添加:
<key>FDMaximumConcurrentTasks</key>
<integer>5</integer>Android:在 AndroidManifest.xml 中配置自定义初始化器:
<!-- 禁用默认初始化器 -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
<!-- 声明自定义初始化器 -->
<provider
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
android:authorities="${applicationId}.flutter-downloader-init"
android:exported="false">
<!-- 修改此数值来配置最大并发任务数 -->
<meta-data
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
android:value="5" />
</provider>数据库表结构
插件使用 SQLite 存储下载任务信息,表结构如下:
CREATE TABLE `task` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`task_id` VARCHAR(256),
`url` TEXT,
`status` INTEGER DEFAULT 0,
`progress` INTEGER DEFAULT 0,
`file_name` TEXT,
`saved_dir` TEXT,
`resumable` TINYINT DEFAULT 0,
`headers` TEXT,
`show_notification` TINYINT DEFAULT 0,
`open_file_from_notification` TINYINT DEFAULT 0,
`time_created` INTEGER DEFAULT 0
);项目链接
- GitHub 仓库:https://github.com/fluttercommunity/flutter_downloader
- pub.dev 发布页:https://pub.dev/packages/flutter_downloader
- 开源协议:BSD-3-Clause
- 最新版本:v1.11.8(2024年7月25日发布)