Flutter文件下载管理插件aria2_dart的使用

Flutter文件下载管理插件aria2_dart的使用

aria2_dart 是一个基于 aria2_ws(Rust)的 Flutter 文件下载管理插件,支持所有平台:Android、iOS、macOS、Windows、Linux 和 Web。

开始使用

开发环境:flutter:3.19.3

cd example && flutter clean
flutter run

pubspec.yaml 中添加依赖:

aria2_dart: ^lastVersion

API

1. 连接

address: aria2 连接地址,例如:ws://127.0.0.1:6800/jsonrpc

await Aria2Plugin().connect(address);

2. 添加下载任务

urls: 远程下载链接

await Aria2Plugin().addTask([...urls]);

3. 监听任务回调

Aria2Plugin().addListen(listen: (MyNotification value) {
  value.when(aria2: (gid, event) {
    // 处理 aria2 事件回调
  }, webSocketConnected: () {
    // 处理连接成功
  }, websocketClosed: () {
    // 处理连接关闭
  });
  // 或者 value.whenOrNull();
});

4. 获取任务详情

gid: 任务ID,由 aria2 返回

Aria2Plugin().getInfo(gid).then((AriaDetail? r) {
  if (r != null) {
     infos[key] = r;
  }
});

5. 断开连接并释放内存

Client? client;
...
client?.dispose(); 

完整示例代码

import 'package:aria2_dart/api/aria.dart';
import 'package:aria2_dart/aria2.dart';
import 'package:aria2_dart/frb_generated.dart';
import 'package:aria2_dart/model/aria_detail.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dd_js_util/dd_js_util.dart';
import 'package:dd_js_util/model/models.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:provider/provider.dart';

Future<void> main() async {
  await RustLib.init();
  runApp(const MyApp());
}

/// 状态管理
class Model extends ChangeNotifier {
  final gids = <String, MyEvent>{};
  final infos = <String, AriaDetail>{};
  Client? client;
  late Timer _timer;

  // 连接
  Future<void> connect(String address) async {
    client = await Aria2Plugin().connect(address);
    Aria2Plugin().addListen(listen: _onListen);
    notifyListeners();
  }

  // 添加任务
  Future<void> addTask(String url) async {
    Aria2Plugin().addTask([url]);
  }

  void cancelTimer() {
    if (!gids.containsValue(MyEvent.start)) {
      debugPrint('canceled timer');
      _timer.cancel();
    }
  }

  void startTimer() {
    debugPrint("start timer task");
    _timer = Timer.periodic(const Duration(seconds: 1), _doGetInfo);
  }

  /// 监听
  void _onListen(MyNotification value) {
    value.whenOrNull(
      aria2: (gid, event) {
        gids[gid] = event;
        notifyListeners();
        if (event == MyEvent.start) {
          startTimer();
        } else {
          delayFunction(() {
            cancelTimer();
          }, 2000);
        }
      },
    );
  }

  void _doGetInfo(Timer timer) {
    gids.forEach((key, value) {
      if (value case MyEvent.start) {
        Aria2Plugin().getInfo(key).then((r) {
          if (r != null) {
            infos[key] = r;
            notifyListeners();
          }
        });
      }
    });
  }

  void cancel() {
    _timer.cancel();
    client?.dispose();
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _textEditController = TextEditingController(text: 'ws://127.0.0.1:6800/jsonrpc');
  final _urlController = TextEditingController(
      text: 'https://alist.azad.asia/d/189yun_2/%E7%BF%BC%E7%8B%90MAYA%E5%AE%8C%E5%85%A8%E8%87%AA%E5%AD%A6%E5%AE%9D%E5%85%B8%E3%80%90%E5%B7%B2%E6%95%B4%E5%90%8817%E7%AB%A0%E3%80%91/%E7%AC%AC04%E7%AB%A0%EF%BC%9A%E3%80%90%E6%A8%A1%E5%9E%8B%E7%AF%87%E3%80%91NURBS%E5%9F%BA%E7%A1%80.zip');

  final model = Model();

  [@override](/user/override)
  void initState() {
    (Connectivity().checkConnectivity());
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(
            title: const Text('aria2下载器'),
          ),
          body: ChangeNotifierProvider(
            create: (context) => model,
            builder: (context, child) {
              return Consumer<Model>(
                builder: (context, value, child) {
                  final Model(client, gids, infos) = value;
                  return SingleChildScrollView(
                    padding: const EdgeInsets.all(12),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Expanded(
                                child: TextField(
                              controller: _textEditController,
                            )),
                            FilledButton(
                                onPressed: _connect, child: const Text("连接服务"))
                          ],
                        ),
                        Row(
                          children: [
                            Expanded(
                              child: TextField(
                                controller: _urlController,
                                maxLines: 3,
                              ),
                            ),
                            FilledButton(
                                onPressed: client == null ? null : _addTask,
                                child: const Text('添加下载任务'))
                          ],
                        ),
                        Padding(
                          padding: const EdgeInsets.symmetric(
                              vertical: 12, horizontal: 8),
                          child:
                              Text('任务列表', style: context.textTheme.titleLarge),
                        ),
                        ...gids.keys.map((e) {
                          final info = infos[e];
                          return _Info(item: info, event: gids[e]);
                        })
                      ],
                    ),
                  );
                },
              );
            },
          )),
    );
  }

  Future<void> _connect() async {
    final url = _textEditController.text;
    if (url.isNotEmpty) {
      model.connect(url);
    }
  }

  Future<void> _addTask() async {
    final url = _urlController.text;
    model.addTask(url);
  }
}

class _Info extends StatelessWidget {
  final AriaDetail? item;
  final MyEvent? event;
  const _Info({this.item, this.event});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final value = event == MyEvent.complete ? 1.0 : item?.percentage ?? 0.01;
    return Card(
      margin: const EdgeInsets.all(12),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(Uri.decodeComponent(
                item?.files.first.path.urlManager.filenameAll ?? '')),
            const SizedBox(
              height: 12,
            ),
            Wrap(
              spacing: 6,
              runSpacing: 6,
              children: [
                //
                Chip(
                    label: Text(
                        '总大小:${ByteModel.create(item?.totalLengthDouble ?? 0.1).format()}')),
                Chip(
                    label: Text(
                        '已下载:${ByteModel.create(item?.completedLengthDouble ?? 0.1).format()}')),
                Chip(label: Text('保存目录:${item?.dir ?? ''}')),
                Chip(label: Text('已下载字节:${item?.completedLength ?? 0}')),
                Chip(label: Text('总字节大小:${item?.totalLength ?? 0}')),
                Chip(
                    label: Text(
                        '下载速度:${ByteModel.create(item?.downloadSpeedDouble ?? 0).format(2)}'))
              ],
            ),
            //
            const SizedBox(
              height: 12,
            ),
            LinearProgressIndicator(
              minHeight: 10,
              borderRadius: BorderRadius.circular(20),
              value: value, // 设置进度值,范围为0.0到1.0
              backgroundColor: Colors.grey, // 设置背景颜色
              valueColor:
                  const AlwaysStoppedAnimation<Color>(Colors.green), // 设置进度条颜色
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter文件下载管理插件aria2_dart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件下载管理插件aria2_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


aria2_dart 是一个基于 Dart 的 Flutter 插件,用于与 aria2 下载工具进行交互。aria2 是一个轻量级、多协议、多源命令行下载工具,支持 HTTP/HTTPS, FTP, SFTP, BitTorrent 和 Metalink 等协议。aria2_dart 插件允许你在 Flutter 应用中集成 aria2 的功能,以便进行文件下载管理。

安装 aria2_dart 插件

首先,你需要在 pubspec.yaml 文件中添加 aria2_dart 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  aria2_dart: ^1.0.0  # 请根据最新版本进行替换

然后,运行 flutter pub get 来安装依赖。

初始化 aria2_dart

在你的 Dart 代码中,首先需要导入 aria2_dart 包,并初始化 Aria2 客户端。

import 'package:aria2_dart/aria2_dart.dart';

final aria2 = Aria2(
  host: '127.0.0.1',  // aria2 RPC 服务器地址
  port: 6800,         // aria2 RPC 服务器端口
  secret: 'your_secret',  // aria2 RPC 密钥(如果有)
);

添加下载任务

你可以使用 addUri 方法来添加一个下载任务。以下是一个简单的示例:

void addDownloadTask() async {
  try {
    final task = await aria2.addUri(
      uris: ['https://example.com/file.zip'],  // 下载链接
      options: {
        'dir': '/path/to/save',  // 保存路径
      },
    );
    print('Download task added: ${task.gid}');
  } catch (e) {
    print('Failed to add download task: $e');
  }
}

查询下载任务状态

你可以使用 tellStatus 方法来查询某个下载任务的状态:

void checkTaskStatus(String gid) async {
  try {
    final status = await aria2.tellStatus(gid);
    print('Task status: ${status.status}');
    print('Downloaded: ${status.completedLength} / ${status.totalLength}');
  } catch (e) {
    print('Failed to check task status: $e');
  }
}

暂停和恢复下载任务

你可以使用 pauseunpause 方法来暂停和恢复下载任务:

void pauseTask(String gid) async {
  try {
    await aria2.pause(gid);
    print('Task paused: $gid');
  } catch (e) {
    print('Failed to pause task: $e');
  }
}

void unpauseTask(String gid) async {
  try {
    await aria2.unpause(gid);
    print('Task resumed: $gid');
  } catch (e) {
    print('Failed to resume task: $e');
  }
}

删除下载任务

你可以使用 remove 方法来删除一个下载任务:

void removeTask(String gid) async {
  try {
    await aria2.remove(gid);
    print('Task removed: $gid');
  } catch (e) {
    print('Failed to remove task: $e');
  }
}

监听下载进度

你可以使用 onDownloadProgress 来监听下载进度:

void listenToProgress(String gid) {
  aria2.onDownloadProgress(gid).listen((progress) {
    print('Download progress: ${progress.completedLength} / ${progress.totalLength}');
  });
}

关闭连接

在应用退出时,记得关闭 aria2 连接:

void closeConnection() async {
  await aria2.close();
}

完整示例

以下是一个完整的示例,展示了如何使用 aria2_dart 插件来添加、查询、暂停、恢复和删除下载任务:

import 'package:aria2_dart/aria2_dart.dart';

final aria2 = Aria2(
  host: '127.0.0.1',
  port: 6800,
  secret: 'your_secret',
);

void main() async {
  // 添加下载任务
  final task = await aria2.addUri(
    uris: ['https://example.com/file.zip'],
    options: {
      'dir': '/path/to/save',
    },
  );
  print('Download task added: ${task.gid}');

  // 查询任务状态
  final status = await aria2.tellStatus(task.gid);
  print('Task status: ${status.status}');

  // 监听下载进度
  aria2.onDownloadProgress(task.gid).listen((progress) {
    print('Download progress: ${progress.completedLength} / ${progress.totalLength}');
  });

  // 暂停任务
  await aria2.pause(task.gid);
  print('Task paused: ${task.gid}');

  // 恢复任务
  await aria2.unpause(task.gid);
  print('Task resumed: ${task.gid}');

  // 删除任务
  await aria2.remove(task.gid);
  print('Task removed: ${task.gid}');

  // 关闭连接
  await aria2.close();
}
回到顶部