ios 为什么使用flutter_downloader时下载失败?

oyjwcjzk  于 2023-01-03  发布在  iOS
关注(0)|答案(2)|浏览(264)

我正在使用flutter_downloader插件为我的应用用户下载文件。在Android和iOS上,下载有时会失败,并显示以下错误消息: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!
t9aqgxwy

t9aqgxwy1#

根据我在GitHub上打开的这个issue的建议,我把我的ifif (status.toString() == "DownloadTaskStatus(3)")改成了if (status.toString() == "DownloadTaskStatus(3)" && progress == 100 &&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);
  }

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

mdfafbf1

mdfafbf12#

我认为这是一个并发问题,在任务被保存到SQLite之前,状态被转换为完成。当我添加一个轻微的延迟时,它工作得很好。
这是我的密码

if (status == DownloadTaskStatus.complete) {
        _state = status;
        context.showSnackbarSuccess(context.locale.downloadSuccess);
        await Future.delayed(const Duration(seconds: 1));
        unawaited(FlutterDownloader.open(taskId: taskId));
        return;
      }

相关问题