Flutter ScreenState Dispose方法异常

时间:2018-02-08 06:15:36

标签: dart flutter

当我尝试从一个屏幕导航到另一个屏幕时,我得到一个例外,说明我正在改变的ScreenState不会在其super.dispose()方法中调用dispose。但是,覆盖dispose方法明确调用super.dispose()

附件是相关的类和日志。任何帮助将不胜感激。

类别:

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();
  }
}

日志:

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.

2 个答案:

答案 0 :(得分:0)

我找到了一个临时解决方法。在进一步检查后,我的dispose方法调用了dispose mixin的ChangeNotifier方法,而不是State<T>类。

我能够通过从班级中删除ChangeNotifier mixin来摆脱这个问题。如果有人知道如何在不摆脱ChangeNotifier混合的情况下解决这个问题,我相信这将是一个更好的解决方案。

答案 1 :(得分:0)

super.dispose() 应该始终是 dispose 函数中的最后一个调用。在调用 super.dispose() 之前必须处理任何其他状态变量/控制器