首页 > 解决方案 > Calling a method with Provider.of(context) inside of dispose() method cause "Looking up a deactivated widget's ancestor is unsafe."

问题描述

When I tried to call a method inside of State dispose method like below.

  @override
  void dispose() {
    Provider.of<AppProvider>(context, listen: false).close();
    super.dispose();
  }

I got this.

The following assertion was thrown while finalizing the widget tree:
Looking up a deactivated widget's ancestor is unsafe.

At this point the state of the widget's element tree is no longer stable.

To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

When the exception was thrown, this was the stack
#0      Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> 
package:flutter/…/widgets/framework.dart:3508
#1      Element._debugCheckStateIsActiveForAncestorLookup 
package:flutter/…/widgets/framework.dart:3522
#2      Element.getElementForInheritedWidgetOfExactType 
package:flutter/…/widgets/framework.dart:3588
#3      Provider.of 
package:provider/src/provider.dart:219
#4      _MySecondPageState.dispose 
package:test_space/main.dart:138
...

This is my example AppProvider

class AppProvider {
  close() {}
}

and I wrapped MaterialApp with AppProvider

return Provider<AppProvider>(
      create: (_) => AppProvider(),
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: HomeScreen(),
        },
      ),
    );

I'm not sure how to do this To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method. I'm currently using provider: ^4.0.2.

I used to do it the same, using Provider.of(context) inside of dispose(), without this exception before. Is this because new flutter version? Also, I realized there is the deactivate() method, should I use deactivate() method instead of dispose() method?

[UPDATED]

  AppProvider _appProvider;
  @override
  void didChangeDependencies() {
    _appProvider = Provider.of<AppProvider>(context, listen: false);
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    _appProvider.close();
    super.dispose();
  }

I could also use deactivate in a certain case

  @override
  void deactivate() {
    Provider.of<AppProvider>(context, listen: false)
        .close();
    super.deactivate();
  }

标签: flutterdartflutter-layout

解决方案


似乎您正在尝试关闭 AppProvider 类中定义的内容。如果 AppProvider 类扩展了 ChangeNotifier,则 change Notifier 类提供了 dispose 方法,您可以重写它,然后只调用 AppProvider 类内部的 close 函数。


推荐阅读