Flutter 使用Flatter_downloader软件包时发生异常

Flutter 使用Flatter_downloader软件包时发生异常,flutter,Flutter,我正在尝试使用Flatter_downloader包下载一些文件(images/pdf)。有一个listView,其中每个ListTiles都包含一个按钮,单击后开始下载,但滚动列表视图时会发生此错误 [错误:flatter/lib/ui/ui\u dart\u state.cc(157)]未处理的异常:“包:flatter\u downloader/src/downloader.dart”:失败的断言:第30行位置12:'_已初始化:Downloader.initialize()只能调用一次

我正在尝试使用Flatter_downloader包下载一些文件(images/pdf)。有一个listView,其中每个ListTiles都包含一个按钮,单击后开始下载,但滚动列表视图时会发生此错误

[错误:flatter/lib/ui/ui\u dart\u state.cc(157)]未处理的异常:“包:flatter\u downloader/src/downloader.dart”:失败的断言:第30行位置12:'_已初始化:Downloader.initialize()只能调用一次

//我的代码如下:

import 'dart:io';
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';
import 'package:permission_handler/permission_handler.dart';

class DownloadFile extends StatefulWidget {

  DownloadFile({this.downloadUrl});
  final String downloadUrl;

  @override
  _DownloadFileState createState() => _DownloadFileState();
}

class _DownloadFileState extends State<DownloadFile> {
  String downloadId;
  String _localPath;

  ReceivePort _port = ReceivePort();

  @override
  void initState(){
    super.initState();
    _init();
  }

  Future<void> _init() async {
    await FlutterDownloader.initialize();
    IsolateNameServer.registerPortWithName(
        _port.sendPort, 'downloader_send_port');
    _port.listen((dynamic data) {
      String id = data[0];
      DownloadTaskStatus status = data[1];
      int progress = data[2];
      print("status: $status");
      print("progress: $progress");
      print("id == downloadId: ${id == downloadId}");
    });
    FlutterDownloader.registerCallback(downloadCallback);

    _localPath = (await _findLocalPath()) + '/Download';
    final savedDir = Directory(_localPath);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      savedDir.create();
    }
  }

  static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
    print(
        'Background Isolate Callback: task ($id) is in status ($status) and process ($progress)');
    final SendPort send =
    IsolateNameServer.lookupPortByName('downloader_send_port');
    send.send([id, status, progress]);
  }

  Future<String> _findLocalPath() async {
    final directory = await getExternalStorageDirectory();
    return directory.path;
  }

  Future<bool> _checkPermission() async {

    if (Theme.of(context).platform == TargetPlatform.android) {
      PermissionStatus permission = await PermissionHandler()
          .checkPermissionStatus(PermissionGroup.storage);
      if (permission != PermissionStatus.granted) {
        Map<PermissionGroup, PermissionStatus> permissions =
        await PermissionHandler()
            .requestPermissions([PermissionGroup.storage]);
        if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
          return true;
        }
      } else {
        return true;
      }
    } else {
      return true;
    }
    return false;
  }
  //----------------------------------------------------------------
  @override
  void dispose() {
    super.dispose();
  }
  //---------------------------------------------------------------
  @override
  Widget build(BuildContext context) {
    return FlatButton(
      onPressed: () async {
        if (await _checkPermission()) {
          final taskId = await FlutterDownloader.enqueue(
            url: widget.downloadUrl,
            savedDir: _localPath,
            showNotification:
            true, // show download progress in status bar (for Android)
            openFileFromNotification:
            true, // click on notification to open downloaded file (for Android)
          );
          downloadId = taskId;
        }
      },
      child: Text('Downloa File',style: TextStyle(color: Colors.teal),)
    );
  }
}
导入'dart:io';
导入“dart:隔离”;
导入“dart:ui”;
进口“包装:颤振/材料.省道”;
进口“包装:颤振_下载器/颤振_下载器.dart”;
导入“package:path_provider/path_provider.dart”;
导入“package:permission_handler/permission_handler.dart”;
类DownloadFile扩展StatefulWidget{
下载文件({this.downloadUrl});
最终字符串下载URL;
@凌驾
_DownloadFileState createState()=>_DownloadFileState();
}
类_DownloadFileState扩展状态{
字符串下载ID;
字符串_localPath;
ReceivePort _port=ReceivePort();
@凌驾
void initState(){
super.initState();
_init();
}
Future _init()异步{
等待下载程序。初始化();
IsolateNameServer.registerPortWithName(
_port.sendPort,“downloader\u send\u port”);
_端口侦听((动态数据){
字符串id=数据[0];
DownloadTaskStatus状态=数据[1];
int进度=数据[2];
打印(“状态:$status”);
打印(“进度:$progress”);
打印(“id==downloadId:${id==downloadId}”);
});
注册回调(downloadCallback);
_localPath=(等待_findLocalPath())+'/Download';
final savedDir=目录(_localPath);
bool hasExisted=wait savedDir.exists();
如果(!已存在){
savedDir.create();
}
}
静态void downloadCallback(字符串id、DownloadTaskStatus状态、int进度){
印刷品(
'后台隔离回调:任务($id)处于状态($status)和进程($progress)';
最终发送端口发送=
IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id、状态、进度]);
}
Future\u findLocalPath()异步{
最终目录=等待getExternalStorageDirectory();
返回directory.path;
}
Future\u checkPermission()异步{
if(Theme.of(context.platform==TargetPlatform.android){
PermissionStatus权限=等待PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
if(权限!=权限状态.已授予){
映射权限=
等待许可处理程序()
.requestPermissions([PermissionGroup.storage]);
if(权限[PermissionGroup.storage]==PermissionStatus.Grated){
返回true;
}
}否则{
返回true;
}
}否则{
返回true;
}
返回false;
}
//----------------------------------------------------------------
@凌驾
无效处置(){
super.dispose();
}
//---------------------------------------------------------------
@凌驾
小部件构建(构建上下文){
返回按钮(
onPressed:()异步{
如果(等待_checkPermission()){
final taskId=wait downloader.enqueue(
url:widget.downloadUrl,
savedDir:\u localPath,
showNotification:
true,//在状态栏中显示下载进度(适用于Android)
openFileFromNotification:
true,//单击通知打开下载的文件(适用于Android)
);
downloadId=taskId;
}
},
子项:文本('Downloa文件',样式:TextStyle(颜色:Colors.teal),)
);
}
}
根据Flatter_downloader软件包中的错误和您收到的错误,您必须调用
FlatterDownloader。初始化
不超过一次

您可以在应用程序的
main
方法中执行此操作,如下所示:

WidgetsFlutterBinding.ensureInitialized();
等待下载程序。初始化();
根据Flatter_downloader软件包中的错误和您收到的错误,您必须调用
FlatterDownloader。初始化
不超过一次

您可以在应用程序的
main
方法中执行此操作,如下所示:

WidgetsFlutterBinding.ensureInitialized();
等待下载程序。初始化();

错误消息表示您多次尝试调用
downloader.initialize()
。如果您的代码表示一个下载按钮,其中会有许多按钮,则会为每个按钮调用initialize()函数,从而导致出现错误。移动
downloader.initialize()
调用,以便在应用程序的生命周期内只调用一次。实际上,它不起作用。移动FlatterDownloader.initialize()时,会发生以下错误:必须至少调用一次FlatterDownloader.initialize()!错误消息表示您已多次尝试调用
downloader.initialize()
。如果您的代码表示一个下载按钮,其中会有许多按钮,则会为每个按钮调用initialize()函数,从而导致出现错误。移动
downloader.initialize()
调用,以便在应用程序的生命周期内只调用一次。实际上,它不起作用。移动FlatterDownloader.initialize()时,会发生以下错误:必须至少调用一次FlatterDownloader.initialize()!