gpt4 book ai didi

flutter - 处理图像/视频和导航器 flutter 的内存使用情况

转载 作者:行者123 更新时间:2023-12-04 14:55:20 25 4
gpt4 key购买 nike

对不起,提前发布了大帖子......
我的应用程序是一个社交网络,其行为与 Instagram 密切相关。
图案 :

  • 用户个人资料(带有缩略图列表,未播放视频)
  • 选择照片(打开带有照片的页面 Navigator.push() 带照片/播放视频
  • 选择另一个用户个人资料(例如在视频的评论中)
  • 再次查看缩略图列表,然后发布照片 - 播放视频等...

  • 这就像一个无限的“配置文件-提要”循环。有了这样的逻辑,在遇到 OutOfMemory 之前,我使用 Navigator.push() 达到或多或少 30 页。错误。
    Flutter 工具只说 lost connection to device但我使用的越多 Navigator应用程序变得越迟钝,最终崩溃,所以我 99% 确定这是由于内存使用。
    由于帖子列表中的滚动,这种情况发生在 100% 的时间,或多或少有 1 页差异。
    如果我不在图片/视频列表中滚动太多,每页的内存使用量或多或少会增加 20MB。
    我已经计划使我的图像更小,但这充其量只是延迟了问题。
    问题 :
  • 是否有可能永远不会遇到 OutOfMemory这种“无限页面”的异常(exception)?
  • 我知道有一个 deactivate() StateFul Widgets 中的方法可以在 Navigator.push 之后使用被调用(dispose() 未被调用,因为我们没有从树中删除任何东西),也许应该在那里做一些工作?
  • 我应该做些什么来处理自己的Navigator堆 ?我不想pop()旧页面,因为我需要返回,直到第一个打开

  • 在这种情况和这种逻辑下,这意味着如果我在 Instagram 浏览 100 页,这也会 100% 崩溃。
    我不确定无论如何有人会走那么远,也许这就是他们所指望的......如果没有办法阻止 OutOfMemory ,唯一的解决方案可能是延迟它,直到用户看到至少 100 页,例如......
    解决方法 我在理论上发现但不确定在代码中是否可行:
    到目前为止,我想到的唯一解决方案是允许用户 push()一定数量的页面,并在 Navigator 中最多保持 20 页堆栈,但不删除第一页。
    所以内存中总会有 20 页。
    如果这是唯一的解决方案,有人可以提供有关如何处理 Navigator 中的特定页面的示例吗?请堆叠?
    另外,我注意到当你返回 Navigator.pop() 时,内存并没有减少。 , 为什么 ?
    编辑 :
    为了显示照片/视频,我基本上使用了 2 packages :
  • flutter_staggered_grid_view : 不是官方包,但拉取请求通过禁用 automaticKeepAlives 使其可用.
  • scrollable_positioned_list :这也适用于构建器和 automaticKeepAlives: false .

  • 我也在应用程序的一部分中使用了 Slivers,但再次使用 SliverStaggeredGrid.countBuilder从前面提到的包。

    最佳答案

    我认为您已经正确指出,根本问题在于推送大量页面的“无限”性质,同时将所有旧页面保留在内存中。
    您尚未发布任何源代码,但我认为此时它不相关。而且从问题描述来看,你看起来很有能力,所以我们大概可以高层次地讨论这个问题。正如一些评论指出的那样,也许每个页面都有优化的空间,但即便如此,也只会拖延问题。简单来说,即使每个页面只是一个Text widget,最终也会遇到OOM的问题。
    解决此问题的一种方法是构建您自己的路由堆栈。在最近的 Flutter 更新中,这变得更加容易,随着他们引入所谓的“Navigator 2.0”,您可以从 official docs 了解更多信息。 .
    本质上,您可以拥有自己的“堆栈”(数据结构)来跟踪用户单击的内容,以便“后退按钮”正常运行。但是在每次跳转时,您不是推送新页面,而是“替换”当前页面。同样,当用户返回时,您不会“弹出”导航器,因为它下面没有任何东西。相反,您查找自己的“历史堆栈”并重新加载上一页。这样,您可以进一步延迟问题(直到您的堆栈溢出,就像本网站的名称一样)。
    一旦完成,也许您可​​以做的进一步优化是保持少数最近的页面处于事件状态,而不是立即销毁它们。例如,也许您可​​以保持 3-5 个最近的页面处于事件状态,以便用户可以更快地返回它们(无需加载)。无论如何,这种可选的优化可能会覆盖 95% 的用例。

    编辑:
    由于你在评论中提到你想要一个 Navigator 2.0 的例子,我拿出我的 IDE 为你做了一个快速演示。
    demo gif
    如您所见,用户可以打开几乎无限数量的新页面,并且可以返回所有页面;然而,在任何给定时间,内存中只有 3 个页面,其他页面在需要时被完全销毁并重新创建。
    我在源代码中写了一些简短的注释来帮助您,但您始终可以从官方文档中学习 Navigator 2.0。
    完整源代码:

    import 'package:flutter/material.dart';

    void main() {
    runApp(MyApp());
    }

    class MyApp extends StatefulWidget {
    @override
    State<MyApp> createState() => _MyAppState();
    }

    class _MyAppState extends State<MyApp> {
    // This list holds the real "stack": anything user has ever clicked.
    // But it only holds minimal info - just the page title.
    final List<String> _titles = [
    'Home Page',
    ];

    @override
    Widget build(BuildContext context) {
    return MaterialApp(
    home: Navigator(
    // The `pages` property here is the most important thing in this demo.
    // It literally represents the stack of pages on the screen.
    // If we make each item in `_titles` into a page, it'll build them all.
    pages: _getPages()
    .map((title) => MaterialPage(
    key: ValueKey(title),
    child: _buildPage(title),
    ))
    .toList(),
    onPopPage: (route, result) {
    // When user pops a page, we remove it from our list as well.
    setState(() => _titles.removeLast());
    return route.didPop(result);
    },
    ),
    );
    }

    List<String> _getPages() {
    print("Current list: $_titles");
    // Uncomment the following line, to skip "optimization" altogether.
    // return _titles;

    // Optimization: only build the top-most 3 pages.
    // First, don't optimize if there are only 3 or fewer pages.
    if (_titles.length <= 3) return _titles;
    // Otherwise, we only return the last 3 items, so the navigator
    // will only build those 3 pages, omitting anything beneath them.
    final last3items = [
    _titles[_titles.length - 3],
    _titles[_titles.length - 2],
    _titles[_titles.length - 1],
    ];
    print("Optimizing, only build the top 3 pages: $last3items");
    return last3items;
    }

    Widget _buildPage(title) {
    return Scaffold(
    appBar: AppBar(title: Text(title)),
    body: GridView.count(
    crossAxisCount: 4,
    children: [
    for (int i = 1; i <= 10; i++)
    Padding(
    padding: EdgeInsets.all(8),
    child: ElevatedButton(
    onPressed: () {
    final time = DateTime.now().millisecondsSinceEpoch;
    setState(() {
    // When user clicks on a button, we add it to our list
    _titles.add('Page $i: $time');
    });
    },
    child: Text('Open Page $i'),
    ),
    ),
    ],
    ),
    );
    }
    }

    关于flutter - 处理图像/视频和导航器 flutter 的内存使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68150393/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com