首页 > 解决方案 > Flutter - 检测内存泄漏

问题描述

我有点困惑,因为我认为颤动中没有内存泄漏,因为没有weak(如果我是正确的)的概念。
我在 iOS 设备上运行它。
我正在尝试播放视频并预先初始化一些视频,以便用户可以毫不拖延地看到它。
为此,我准备了六个VideoPlayerController,并在当前视频播放时使它们始终被初始化。
当前一个旁边还有三个初始化VideoPlayerController,当前一个之前还有两个初始化,如下图所示。 使用这种逻辑,我可以非常流畅地来回播放视频。但是在播放了大约十个视频后,由于内存问题,应用程序崩溃了。我尝试了每一个功能Future, async, await,但仍然吃掉了很多回忆。我不确定,但可能是NotificationListener
既然不onNotification返回或者这与什么有关吗? 有谁知道如何解决这个内存问题?boolFuturemain thread

代码:

    class _SwiperScreenState extends State<SwiperScreen> {
      VideoPlayerController _firstController;
      VideoPlayerController _secondController;
      VideoPlayerController _thirdController;
      VideoPlayerController _fourthController;
      VideoPlayerController _fifthController;
      VideoPlayerController _sixthController;
      List<VideoPlayerController> _controllers;
      List<String> urls = [
        'https://firebasestorage.googleapis.com/v0/b/waitingboy-34497.appspot.com/o/video%2F8-21%2F1534825377992OsfJfKsdf90K8sf?alt=media&token=12245ee4-1598-4f7e-ba28-a9eb72ca474e',
        'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
        'https://firebasestorage.googleapis.com/v0/b/waitingboy-34497.appspot.com/o/video%2F8-21%2F1534825377992OsfJfKsdf90K8sf?alt=media&token=12245ee4-1598-4f7e-ba28-a9eb72ca474e',
        'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
      ];
      int currentIndex = 0; //refer to current playing controller index
      int videosIndex = 0; //refer to current playing urls index

      bool _didGetNotification(ScrollNotification notification) {
        if (notification is UserScrollNotification) {
          if (notification.direction.toString() == 'ScrollDirection.reverse') {
        //swipe to left so add one more video
            videosIndex++;
        //modify index so that always in the range of 0 ~ 5.
            if (currentIndex <= 2) {
              final int prepareIndex = currentIndex + 3;
              urls.add(
                  'https://firebasestorage.googleapis.com/v0/b/waitingboy-34497.appspot.com/o/video%2F8-21%2F1534825377992OsfJfKsdf90K8sf?alt=media&token=12245ee4-1598-4f7e-ba28-a9eb72ca474e');
              _initVideo(urls[videosIndex], prepareIndex);
            } else {
              final int prepareIndex = (currentIndex + 3) - 6;
              urls.add(
                  'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4');
              _initVideo(urls[videosIndex], prepareIndex);
            }
          }
          if (notification.direction.toString() == 'ScrollDirection.forward') {
       //swipe to right so back one more video
            videosIndex--;
       //modify index so that always in the range of 0 ~ 5 .
            if (currentIndex >= 2) {
              final int videoIndex = videosIndex - 2;
              final int prepareIndex = currentIndex - 2;
              _initVideo(urls[videoIndex], prepareIndex);
            } else {
              final int videoIndex = videosIndex - 2;
              final int prepareIndex = 4 + currentIndex;
              _initVideo(urls[videoIndex], prepareIndex);
            }
          }
        }
        return true;
      }

      Future _initVideo(String url, int initIndex) async {
        if (_controllers[initIndex] != null) {
          await _controllers[initIndex].dispose();
        }

        _controllers[initIndex] = new VideoPlayerController.network(url);
        await _controllers[initIndex].initialize().then((_) async => await _controllers[initIndex].setLooping(true));
        setState(() {});
      }

      Future _initFirstThree() async {
         for  (int i = 1; i < urls.length; i++) {
          await _initVideo(urls[i], i);
        }
      }

      @override
      void initState() {
        _controllers = [
          _firstController,
          _secondController,
          _thirdController,
          _fourthController,
          _fifthController,
          _sixthController
        ];
        _initVideo(urls[0], 0).then((_) => _controllers[0].play());
        _initFirstThree();
        super.initState();
      }

      @override
      void deactivate() {
        _controllers[currentIndex].setVolume(0.0);
        _controllers[currentIndex].pause();
        super.deactivate();
      }

      @override
      void dispose() {
        _controllers.forEach((con) {
          con.dispose();
        });
        super.dispose();
      }

      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Swiper'),
            actions: <Widget>[
              new IconButton(
                icon: new Icon(Icons.disc_full),
                onPressed: () {
                  Navigator
                      .of(context)
                      .push(MaterialPageRoute(builder: (context) => Dissmiss()));
                },
              )
            ],
          ),
          body: new NotificationListener(
            onNotification: _didGetNotification,
            child: new Swiper(
              itemCount: 6,
              itemBuilder: (BuildContext context, int index) {
                return _controllers[index].value.initialized
                    ? new AspectRatio(
                        aspectRatio: _controllers[index].value.aspectRatio,
                        child: new VideoPlayer(_controllers[index]),
                      )
                    : new Center(child: new CircularProgressIndicator());
              },
              loop: urls.length > 6 ? true : false,
              onIndexChanged: (i) async {
                currentIndex = i;
                final int pauseIndex = i == 0 ? 5 : i - 1;
                await _controllers[pauseIndex].pause().then((_) async {
                  await _controllers[i].play();
                });
              },
            ),
          ),
        );
      }
    }

标签: flutter

解决方案


推荐阅读