How to dispose Stateful Widget completely?

8,139 views
Skip to first unread message

Niyazi Toros

unread,
Sep 12, 2018, 2:16:06 AM9/12/18
to Flutter Dev
Hi,

I call my stateful widget page and get some info from server. If no info found it warns user that there isn't any info.
From drawer back button I go back to previous page. If I keep repeat back and forth very fast I get an error on console message in my IntelliJ IDE as;

E/flutter (22681): [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
E/flutter (22681): setState() called after dispose(): _BillsPayWaterState#66be5(lifecycle state: defunct, not mounted)
E/flutter (22681): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (22681): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter (22681): #0      State.setState.<anonymous closure> 


In my statefull widget I have @override void initState() and I also have @override void dispose() 

My question is when I use drawer back button, How can I dispose my Stateful Widget completely?

Olaide Nojeem Ekeolere

unread,
Sep 12, 2018, 2:49:39 AM9/12/18
to Niyazi Toros, Flutter Dev
Hi,
Because you calling setState on a disposed widget. Always check if widget mounted property is true before calling setState.
if(mounted){
    setState((){
         //do whatever
      });
}
You will get no more errors

--
You received this message because you are subscribed to the Google Groups "Flutter Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Niyazi Toros

unread,
Sep 12, 2018, 3:10:05 AM9/12/18
to Flutter Dev
@Olaide Nojeem thanks for reply, and here is my code....

Problem is If I keep repeat back and forth very fast I get an error...

This is the call for widget

onTap: () {
Navigator.push(
  context,
  SlideRightRoute(widget: new BillsWaterPay(“S02")),
);
}



And this the BillsWaterPay widget


List<List<dynamic>> _userAskBills;


// TODO: KURUM KODU - SABIT TELEFON

String _kurumKodu = "";

String _noDataText = "";


class BillsWaterPay extends StatefulWidget {

  final String title;


  BillsWaterPay(this.title);


  @override

  _BillsWaterPayState createState() =>

      _BillsWaterPayState();

}


class _BillsWaterPayState extends State<BillsWaterPay> {


  @override

  void initState() {

    // TODO: implement initState

    super.initState();

    _kurumKodu = widget.title;

_userAskBills;

_noDataText;

_loadEverything();

}


Future _loadEverything() async {

await _getDataFromServer();

}


Future _getDataFromServer() async() {

if no data

setState

_noDataText = “No Data”;  // In here I get an error setState called after dispose

}



@override

void dispose() {

  super.dispose();

      _kurumKodu = widget.title;

_userAskBills;

_noDataText;

}


Olaide Nojeem Ekeolere

unread,
Sep 12, 2018, 3:22:52 AM9/12/18
to Niyazi Toros, Flutter Dev

if(mounted&&noData){
    setState((){
         noDataText = “No Data”;
      });
}

Niyazi Toros

unread,
Sep 12, 2018, 3:37:53 AM9/12/18
to Flutter Dev
thanks for the update.

When I call SlideRightRoute(widget: new BillsWaterPay(“S02")), am I not creating a new widget? and void dispose() I assume that I dispose the old widget. So, I call few times like this SlideRightRoute(widget: new BillsWaterPay(“S02")), SlideRightRoute(widget: new BillsWaterPay(“S03")), SlideRightRoute(widget: new BillsWaterPay(“S04")) and the dispose I use I assume that dispose the widget object that is created. if mounted is false what should I do? 

class BillsWaterPay extends StatefulWidget {
  final String title;
  BillsWaterPay(this.title);
  @override
  _BillsWaterPayState createState() => _BillsWaterPayState();
}

Can I use super key in here so every call to this widget will be different? If so, how to use super key in here and how to call them?

 

Olaide Nojeem Ekeolere

unread,
Sep 12, 2018, 3:43:13 AM9/12/18
to Niyazi Toros, Flutter Dev
If mounted is false, it means the widget is no longer active. Even when you dispose the widget the Future will still be running so that is why you have to check mounted in your Future before calling setState.

--

Niyazi Toros

unread,
Sep 12, 2018, 5:38:26 AM9/12/18
to Flutter Dev
Thanks Olaide...

Olaide Nojeem Ekeolere

unread,
Sep 12, 2018, 7:15:56 AM9/12/18
to Niyazi Toros, Flutter Dev
Glad I could help.

On Wed, 12 Sep 2018 at 10:38 AM, Niyazi Toros <niyazi...@gmail.com> wrote:
Thanks Olaide...
Reply all
Reply to author
Forward
0 new messages