Почему мои загрузки иногда терпят неудачу при использовании flutter_downloader? - PullRequest
0 голосов
/ 24 февраля 2020

Я использую плагин flutter_downloader для загрузки файлов для пользователей моего приложения. И на Android, и на iOS загрузка иногда завершается с этим сообщением об ошибке: flutter: not found task corresponding to given task id. С iOS иногда мои задачи загрузки просто ставились в очередь и вообще не выполнялись. Иногда они работают без сбоев.

Я обнаружил, что при запуске flutter clean и перестройке приложения это на некоторое время исчезает (загрузка прошла успешно, и файл может быть открыт в соответствующих приложениях), но когда я создаю приложение Flutter снова после изменения чего-то ошибка возвращается. Я включил Android трафик открытого текста c, но безрезультатно.

Вот минимальное воспроизведение моего кода:

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!

1 Ответ

0 голосов
/ 26 февраля 2020

В соответствии с предложениями по этому выпуску , которые я открыл на GitHub, я изменил свой if с if (status.toString() == "DownloadTaskStatus(3)") на if (status.toString() == "DownloadTaskStatus(3)" && progress == 100 &&id!=null).

Для удобства я также запросил указанную задачу c, которую мы ищем в моей функции 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);
  }

Теперь все работает гладко. Просто примечание: всякий раз, когда я делаю горячую ссылку sh, задачи просто ставятся в очередь и не выполняются. Пришлось прервать и перестроить приложение, чтобы загрузки снова работали правильно.

...