Страницы просмотра страниц не удаляются, в приложении заканчивается память и происходит сбой

#flutter

Вопрос:

У меня в приложении есть фотогалерея, которая использует a PageView для отображения одного изображения с высоким разрешением на странице.

Быстро просматривая галерею, я могу надежно завершить работу своего приложения. В моем случае на iPhone 12 Pro 27-е изображение убивает его на 2,8 ГБ памяти:

 * thread #12, name = 'io.flutter.1.io', stop reason = EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=2867 MB, unused=0x0)
    frame #0: 0x00000001de32c64c libsystem_platform.dylib`_platform_memmove   76
libsystem_platform.dylib`_platform_memmove:
->  0x1de32c64c < 76>: stnp   q0, q1, [x3]
    0x1de32c650 < 80>: add    x3, x3, #0x20             ; =0x20
    0x1de32c654 < 84>: ldnp   q0, q1, [x1]
    0x1de32c658 < 88>: add    x1, x1, #0x20             ; =0x20
Target 0: (Runner) stopped.

 

Выглядит загадочно, но ясно говорит о том, что вся доступная память израсходована.

Некоторые изображения имеют наложение, например переключатель или поле формы, как часть страницы. Я понял, что их состояние сохраняется, пока я прокручиваю назад и вперед. Поскольку я использую PageView.builder конструктор, я на самом деле ожидал, что страницы будут удалены, и при прокрутке в памяти останется только фиксированное окно страниц вокруг текущей страницы. Когда я удаляюсь из галереи после прокрутки 20 изображений (чтобы весь просмотр страницы был удален) и возвращаюсь в галерею, я могу провести еще 20 изображений и повторить это без сбоев. Так что, похоже, избавление от PageView этого очищает память.

Как я могу принудительно удалить страницы?

Google дает мне много вопросов и ответов о том, как поддерживать страницы в PageView живом состоянии, и это подтверждает мое ожидание, что просмотр страниц должен распоряжаться ресурсами, если я не скажу ему явно что-то другое.

Краткие сведения:

  1. Я использую PageView.builder
  2. Состояние страницы, по-видимому, сохраняется для всех страниц по умолчанию
  3. Приложение выходит из строя после отображения x страниц

Вот мой код просмотра страниц для справки:

 PageView.builder(
  clipBehavior: Clip.hardEdge,
  physics: const BouncingScrollPhysics(),
  itemBuilder: (context, index) => GalleryCustomChild(image: viewModel.images[index]),
  itemCount: viewModel.images.length,
  controller: viewModel.pageController,
)

class GalleryCustomChild extends StatelessWidget {
  final ImageData image;

  const GalleryCustomChild({required this.image, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return PhotoView(
      minScale: PhotoViewComputedScale.contained,
      maxScale: PhotoViewComputedScale.covered,
      initialScale: PhotoViewComputedScale.contained,
      backgroundDecoration: const BoxDecoration(color: Colors.black),
      imageProvider: FileImage(
        File(image.filePath),
      ),
    );
  }
}
 

Комментарии:

1. Привет, я думаю, вы не избавляетесь от своего pageViewController. Пожалуйста, попробуйте избавиться от контроллера, переопределив метод dispose ().

2. Спасибо вам, ребята, за вклад 🙂 Я попробовал и то, и другое, но, к сожалению, безрезультатно. Размер кэшированного изображения печатается как 0 или какое-то разумное значение, но сбой все равно произойдет.

3. Есть какие-нибудь новости по этому поводу? Я сталкиваюсь с точно такой же проблемой. Я показываю изображения в виджете просмотра страниц. Я могу прокрутить около 30 полноразмерных изображений (от 1 до 2 МБ) на своем iPhone 11 pro, прежде чем приложение внезапно выйдет из строя. На странице памяти в инструментах разработки Dart я вижу, что использование памяти продолжает увеличиваться при листании страниц. Для меня, однако, когда я удаляю виджет просмотра страниц, скажем, после 25 пролистываний без сбоев, и продолжаю работу со следующим изображением, он вылетает примерно через 5 пролистываний. Мне кажется, что изображения кэшируются и очищаются, когда занимаемое пространство становится слишком большим.

4. Мы использовали photo_view пакет. Смотрите эту все еще открытую проблему, в ней есть возможное исправление: github.com/bluefireteam/photo_view/issues/478