Flutter ScreenState Dispose method exception

ぐ巨炮叔叔 提交于 2021-01-28 05:31:13

问题


When I try to navigate away from one screen to another in flutter, I am getting an exception stating that the ScreenState that I am changing away from does not call super.dispose() in its dispose method. However, the overriden dispose method clearly calls super.dispose().

Attached are the relevant class and the logs. Any help would be greatly appreciated.

Class:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:kickit/screens/feed_screen.dart';
import 'package:kickit/screens/profile_screen.dart';
import 'package:kickit/screens/talk_screen.dart';
import 'package:kickit/utils/values/internal_strings.dart';
import 'package:kickit/utils/values/strings.dart';
import 'package:kickit/utils/values/values.dart';

/// Main screen that contains three screens within for displaying information.
/// Contains a:
/// - [TalkScreen]
/// - [FeedScreen]
/// - [ProfileScreen]
class MainScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _MainScreenState();
  }
}

/// Manages the state of [MainScreen].
class _MainScreenState extends State<MainScreen> with ChangeNotifier {
  // A PageController to manage which screen is currently shown.
  PageController _pageController;

  // The current page that is in focus.
  // - 0 => ConversationScreen
  // - 1 => FeedScreen
  // - 2 => ProfileScreen
  int _page = 1;

  /// Initializes this [MainScreen], setting the initial screen to the
  /// [FeedScreen] due to [_page] starting at 1.
  @override
  void initState() {
    super.initState();
    _pageController = new PageController(
      initialPage: _page,
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      // key: new ValueKey(InternalStrings.mainScaffoldKey),
      appBar: _appBar(),
      body: _mainScreens(),
      bottomNavigationBar: _bottomBar(),
    );
  }

  /// Gets an [AppBar] that will be shown across all of the screens controlled
  /// by this [MainScreen]
  AppBar _appBar() {
    return new AppBar(
      // key: new ValueKey(InternalStrings.mainAppBarKey),
      centerTitle: true,
      title: new Text(
        Strings.title,
        style: Theme.of(context).textTheme.title,
      ),
      actions: <Widget>[
        new IconButton(
          key: new ValueKey(InternalStrings.mainSettingsButtonKey),
          icon: new Icon(Icons.settings),
          onPressed: () => Navigator
              .of(context)
              .pushReplacementNamed(InternalStrings.mainScreenRoute),
        ),
      ],
    );
  }

  /// Gets a [PageView] storing the screens controlled by this [MainScreen].
  PageView _mainScreens() {
    return new PageView(
      // key: new ValueKey(InternalStrings.mainPageViewKey),
      controller: _pageController,
      onPageChanged: _onPageChanged,
      children: <Widget>[
        new Container(
          child: new TalkScreen(),
        ),
        new Container(
          child: new FeedScreen(),
        ),
        new Container(
          child: new ProfileScreen(),
        ),
      ],
    );
  }

  /// Gets a [BottomNavigationBar] that will be shown across all of the screens
  /// controlled by this [MainScreen]
  BottomNavigationBar _bottomBar() {
    return new BottomNavigationBar(
      // key: new ValueKey(InternalStrings.mainBottomBarKey),
      items: [
        new BottomNavigationBarItem(
          icon: new Icon(Icons.people),
          title: new Text(Strings.mainBottomBarTalk),
        ),
        new BottomNavigationBarItem(
          icon: new Icon(Icons.list),
          title: new Text(Strings.mainBottomBarFeed),
        ),
        new BottomNavigationBarItem(
          icon: new Icon(Icons.person),
          title: new Text(Strings.mainBottomBarProfile),
        ),
      ],
      onTap: _onNavigationTap,
      currentIndex: _page,
    );
  }

  /// Handles a tap on the bottom navigation bar.
  void _onNavigationTap(int page) {
    _pageController.animateToPage(
      page,
      duration: Values.animationShort,
      curve: Curves.ease,
    );
  }

  /// Handles a page change and updates the bottom bar.
  void _onPageChanged(int page) {
    this._pageController.notifyListeners();
    setState(() {
      this._page = page;
    });
  }

  /// Dispose of the [PageController] when disposed.
  @override
  void dispose() {
    super.dispose();
    _pageController.dispose();
  }
}

Logs:

I/flutter (18130): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (18130): The following assertion was thrown while finalizing the widget tree:
I/flutter (18130): MainScreenState.dispose failed to call super.dispose.
I/flutter (18130): dispose() implementations must always call their superclass dispose() method, to ensure that all the
I/flutter (18130): resources used by the widget are fully released.
I/flutter (18130): 
I/flutter (18130): When the exception was thrown, this was the stack:
I/flutter (18130): #0      StatefulElement.unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:3771)
I/flutter (18130): #1      StatefulElement.unmount (package:flutter/src/widgets/framework.dart:3776)
I/flutter (18130): #2      _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1670)
I/flutter (18130): #3      _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #4      ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #5      _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #6      _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #7      ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #8      _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #9      _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #10     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4584)
I/flutter (18130): #11     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #12     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #13     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4584)
I/flutter (18130): #14     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #15     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #16     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4584)
I/flutter (18130): #17     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #18     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #19     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #20     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #21     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #22     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #23     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #24     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #25     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4584)
I/flutter (18130): #26     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #27     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #28     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4584)
I/flutter (18130): #29     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #30     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #31     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #32     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #33     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #34     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:4584)
I/flutter (18130): #35     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #36     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #37     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #38     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #39     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #40     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #41     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #42     _InactiveElements._unmount.<anonymous closure> (package:flutter/src/widgets/framework.dart:1668)
I/flutter (18130): #43     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:3644)
I/flutter (18130): #44     _InactiveElements._unmount (package:flutter/src/widgets/framework.dart:1666)
I/flutter (18130): #45     ListIterable.forEach (dart:_internal/iterable.dart:39)
I/flutter (18130): #46     _InactiveElements._unmountAll (package:flutter/src/widgets/framework.dart:1679)
I/flutter (18130): #47     BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2296)
I/flutter (18130): #48     BuildOwner.lockState (package:flutter/src/widgets/framework.dart:2128)
I/flutter (18130): #49     BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:2295)
I/flutter (18130): #50     BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:623)
I/flutter (18130): #51     BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208)
I/flutter (18130): #52     BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990)
I/flutter (18130): #53     BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930)
I/flutter (18130): #54     BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842)
I/flutter (18130): #55     _invoke (file:///b/build/slave/Linux_Engine/build/src/flutter/lib/ui/hooks.dart:120)
I/flutter (18130): #56     _drawFrame (file:///b/build/slave/Linux_Engine/build/src/flutter/lib/ui/hooks.dart:109)
I/flutter (18130): ════════════════════════════════════════════════════════════════════════════════════════════════════
Application finished.

回答1:


I have found a temporary workaround. Upon further inspection my dispose method was calling the dispose method of the ChangeNotifier mixin rather than the State<T> class.

I was able to get rid of this issue by removing the ChangeNotifier mixin from my class. If anyone knows how to solve this issue without getting rid of the ChangeNotifier mixing, I'm sure that would be a better solution.



来源:https://stackoverflow.com/questions/48678788/flutter-screenstate-dispose-method-exception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!