为什么有时会使用flutter_downloader下载失败?
我正在使用 flutter_downloader 插件为我的应用程序用户下载文件.在Android和iOS上,下载有时会失败,并显示以下错误消息: flutter:找不到与给定任务ID对应的任务
.使用iOS,有时我的下载任务只会被排入队列,而根本不会执行.有时它们运行平稳.
I'm using the flutter_downloader plugin to download files for my app users. On both Android and iOS, downloads sometimes fail with this error message: flutter: not found task corresponding to given task id
. With iOS, sometimes my download tasks would just be enqueued and not executed at all. Sometimes they run smoothly.
我发现运行 flutter clean
并重新构建应用程序似乎使这种情况消失了一点(下载成功并且可以在相关应用程序中打开文件),但是当我在之后再次构建Flutter应用程序时改变某些东西,错误又回来了.我已启用Android明文流量,但无济于事.
I found that running flutter clean
and rebuilding the app seems to make this disappear for a bit (download successful and file can be opened in relevant apps), but when I build the Flutter app again after changing something, the error comes back. I've enabled Android cleartext traffic, to no avail.
这是我的代码的最小复制:
Here's a minimal reproduction of my code:
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
void main(){
_initializeFlutterDownloader();
runApp(MyApp());
}
_initializeFlutterDownloader()async{
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize();
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Downloader Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Downloader Example'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ReceivePort _port = ReceivePort();
@override
void initState() {
super.initState();
_downloadListener();
}
static void downloadCallback(
String id, DownloadTaskStatus status, int progress) {
final SendPort send =
IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id, status, progress]);
}
_downloadListener() {
IsolateNameServer.registerPortWithName(
_port.sendPort, 'downloader_send_port');
_port.listen((dynamic data) {
String id = data[0];
DownloadTaskStatus status = data[1];
if (status.toString() == "DownloadTaskStatus(3)") {
FlutterDownloader.open(taskId: id);
}
});
FlutterDownloader.registerCallback(downloadCallback);
}
void _download() async {
String _localPath =
(await findLocalPath()) + Platform.pathSeparator + 'Example_Downloads';
final savedDir = Directory(_localPath);
bool hasExisted = await savedDir.exists();
if (!hasExisted) {
savedDir.create();
}
String _url =
"https://www.colonialkc.org/wp-content/uploads/2015/07/Placeholder.png";
final download = await FlutterDownloader.enqueue(
url: _url,
savedDir: _localPath,
showNotification: true,
openFileFromNotification: true,
);
}
Future<String> findLocalPath() async {
final directory =
// (MyGlobals.platform == "android")
// ?
await getExternalStorageDirectory();
// : await getApplicationDocumentsDirectory();
return directory.path;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _download,
child: Icon(Icons.file_download),
),
);
}
}
这是我的 flutter医生
结果:
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.14.6 18G95, locale en-ID)
• Flutter version 1.12.13+hotfix.5 at /Users/ictmacbook2/flutter
• Framework revision 27321ebbad (3 months ago), 2019-12-10 18:15:01 -0800
• Engine revision 2994f7e1e6
• Dart version 2.7.0
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at /Users/ictmacbook2/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-29, build-tools 29.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.3, Build version 10G8
• CocoaPods version 1.7.5
[✓] Android Studio (version 3.5)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 43.0.1
• Dart plugin version 191.8593
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] VS Code (version 1.42.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.8.1
[✓] Connected device (1 available)
• iPad • 1ba96acf871024d9097348342ff6d84fe5013c16 • ios • iOS 12.4.1
• No issues found!
根据此问题我在GitHub上打开,我将 if
从 if(status.toString()=="DownloadTaskStatus(3)")
更改为if(status.toString()=="DownloadTaskStatus(3)"&& progress == 100& id!= null)
.
According to the suggestions on this issue I opened on GitHub, I changed my if
from if (status.toString() == "DownloadTaskStatus(3)")
to if (status.toString() == "DownloadTaskStatus(3)" && progress == 100 &&id!=null)
.
出于很好的考虑,我还查询了我们在 downloadListener
函数中正在寻找的特定任务,如下所示:
For good measure, I also queried for the specific task we're looking for in my downloadListener
function, like so:
_downloadListener() {
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen((dynamic data) {
String id = data[0];
DownloadTaskStatus status = data[1];
int progress = data[2];
if (status.toString() == "DownloadTaskStatus(3)" && progress == 100 && id != null) {
String query = "SELECT * FROM task WHERE task_id='" + id + "'";
var tasks = FlutterDownloader.loadTasksWithRawQuery(query: query);
//if the task exists, open it
if (tasks != null) FlutterDownloader.open(taskId: id);
}
});
FlutterDownloader.registerCallback(downloadCallback);
}
现在一切运行顺利.请注意,每当我进行热刷新时,任务都将被排队,而不执行.必须中止并重建应用程序,下载才能再次正常运行.
It all runs smoothly now. Just a note, whenever I hot refresh, the tasks would just be enqueued and not executed. Had to abort and rebuild the app for the downloads to work properly again.