为啥我的下载有时会使用 flutter_downloader 失败?

Posted

技术标签:

【中文标题】为啥我的下载有时会使用 flutter_downloader 失败?【英文标题】:Why do my downloads fail sometimes using flutter_downloader?为什么我的下载有时会使用 flutter_downloader 失败? 【发布时间】:2020-06-07 20:06:24 【问题描述】:

我正在使用 flutter_downloader 插件为我的应用用户下载文件。在 androidios 上,下载有时会失败并显示以下错误消息:flutter: not found task corresponding to given task id。在 iOS 中,有时我的下载任务只是被排入队列而根本不执行。有时它们运行平稳。

我发现运行flutter clean并重新构建应用程序似乎会使它消失一段时间(下载成功并且可以在相关应用程序中打开文件),但是当我更改某些内容后再次构建Flutter应用程序时,错误来了背部。我已启用 Android 明文流量,但无济于事。

这是我的代码的最小复制:

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 doctor 结果:

[✓] 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!

【问题讨论】:

更新了您的issue on github,提供了一些可能有帮助的信息。即,查明了 iOS 上的错误位置 ERROR_INVALID_TASK_ID 和 Android 上的 invalid_task_id。找到解决方案后,请确保将其发布在此处并被接受。我认为问题在于任务入队不成功或入队任务恢复不成功。 【参考方案1】:

根据我在GitHub上打开的这个issue的建议,我把我的ifif (status.toString() == "DownloadTaskStatus(3)")改成了if (status.toString() == "DownloadTaskStatus(3)" &amp;&amp; progress == 100 &amp;&amp;id!=null)

为了更好地衡量,我还在downloadListener 函数中查询了我们正在寻找的特定任务,如下所示:

  _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);
  

现在一切顺利。请注意,每当我热刷新时,任务只会被排队而不执行。必须中止并重建应用程序才能使下载再次正常工作。

【讨论】:

如果插件有问题,我们可以联系我吗

以上是关于为啥我的下载有时会使用 flutter_downloader 失败?的主要内容,如果未能解决你的问题,请参考以下文章

为啥有时我的页面中的 UI 有时会出现有时不出现?

为啥将 .Wait() 添加到我的 Task 有时会允许 Task 使用主线程?

为啥我的比较方法有时会抛出 IllegalArgumentException?

为啥我的背景图像有时会消失?

为啥发布版本有时会崩溃,而调试版本则不会?

为啥动画有时会根据经过的时间使用步骤来完成?