Продолжить asyn c задачу после запуска, даже если пользователь переходит на другой экран во флаттере - PullRequest
1 голос
/ 14 июля 2020

Я хочу продолжить асинхронную c задачу в фоновом режиме после запуска с одного экрана независимо от того, переходит ли пользователь на другой экран.

Из экрана списка изображений пользователь может выбрать несколько изображений, и начнется загрузка изображений. Функции для загрузки изображений приведены ниже.

dynamic _onUploadAllAssets(String albumId, AlbumManager albumManager,
      List<Asset> imageList, context, albumBloc) async {
    for (int i = 0; i < imageList.length; i++) {
      await uploadAsset(
          imageList.first, albumId, albumManager, 0, context, albumBloc);
      albumBloc.fetchAllImages(albumId);
      imageList.remove(imageList.first);
      albumBloc.getSelectedImage(imageList);
    }
  }

dynamic uploadAsset(Asset asset, String albumId, AlbumManager albumManager,
      int index, context, albumBloc) async {
    final String uuid = Uuid().v1();
    final height = MediaQuery.of(context).size.height / 2;

    final width = asset.originalWidth * height / asset.originalHeight;

    final imageByte = await asset.getByteData(quality: 100);

    final base64Image = base64Encode(imageByte.buffer.asUint8List());
    await uploadAlbumImage(albumId, base64Image, uuid, false, index, albumBloc);
    final compressedImageBytes = await asset.getThumbByteData(
      width.round(),
      height.round(),
    );
    final compressedImageU8 = compressedImageBytes.buffer.asUint8List();
    final compressedBase64 = base64Encode(compressedImageU8);
    await uploadAlbumImage(
        albumId, compressedBase64, uuid, true, index, albumBloc);
  }

Future<bool> uploadAlbumImage(String albumId, String base64Image, String uuid,
      bool isThumbnail, int index, albumBloc) async {
    await albumManager.connectFirebase();
    final Directory systemTempDir = Directory.systemTemp;

    if (albumManager.circleAlbumCacheDir == null) {
      await albumManager.getCacheDirectory(albumId);
    }

    final encryptor = encryption.StringEncryption();
    final encryptedImage = await encryptor.getEncryption(base64Image);

    final String prefix = isThumbnail ? 'thumbnail_' : 'img_';

    final File file = File('${systemTempDir.path}/tmp$prefix$uuid.txt');
    if (file.existsSync()) {
      await file.delete();
    }
    await file.create();

    await file.writeAsString(encryptedImage);

    final StorageReference preRef =
        albumManager.storageReference.child(albumId);

    final StorageReference thumbnailRef =
        preRef.child('thumbnail').child('thumbnail_$uuid.txt');

    final StorageReference imageRef =
        preRef.child('images').child('img_$uuid.txt');

    final StorageReference ref = isThumbnail ? thumbnailRef : imageRef;

    final StorageUploadTask task = ref.putFile(
      file,
      StorageMetadata(
        contentLanguage: 'en',
        customMetadata: <String, String>{'activity': 'uploadEventImage'},
      ),
    );
    task.events.listen((storageTaskEvent) {
      final _progess = storageTaskEvent.snapshot.bytesTransferred.toDouble() /
          storageTaskEvent.snapshot.totalByteCount.toDouble();
      albumBloc.syncFileUploading(uuid, isThumbnail, _progess, index);
    });
    await task.onComplete;

    if (!task.isSuccessful) {
      ref.delete();
      await file.delete();
    } else if (isThumbnail) {
      final String thumbnailUrl = await thumbnailRef.getDownloadURL();
      final String imageUrl = await imageRef.getDownloadURL();
      await albumManager.addImageToFolder(
          albumId, uuid, thumbnailUrl, imageUrl, true);
      await albumManager.getCacheDirectory(albumId);
      albumManager.cacheImage(
          base64Image, '${albumManager.circleAlbumCacheDir}/thumb_$uuid.png');
    } else {
      await albumManager.getCacheDirectory(albumId);
      albumManager.cacheImage(
          base64Image, '${albumManager.circleAlbumCacheDir}/img_$uuid.png');
    }

    await file.delete();
    return task.isSuccessful;
  }

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

Для l oop прекращать выполнение, когда пользователь переходит на другой экран или возвращается к предыдущему экрану. Я хочу продолжить выполнение для l oop, пока не будут загружены все изображения.

Ответы [ 2 ]

0 голосов
/ 14 июля 2020

Если вы хотите работать в фоновом режиме, не показывая пользователю никаких подсказок о ходе выполнения, тогда вы должны использовать «изоляты». Но если вы хотите показать пользователю ход выполнения задачи, создайте виджет, содержащий progressBar в качестве виджета, и на каждой странице используйте его как дочерний виджет.

0 голосов
/ 14 июля 2020

Встраивание _onUploadAllAsset в другую асинхронную функцию должно работать, нет? (без использования ключевого слова await ...)

...