Toast.mNextView and FrameLayout possible leak - how to trace the cause?

536

This toast leak is caused by MethodCallHandlerImpl.mToast in ponnamkarthik/FlutterToast.

I filed an issue here: https://github.com/ponnamkarthik/FlutterToast/issues/292

Share:
536
BradG
Author by

BradG

Updated on December 28, 2022

Comments

  • BradG
    BradG over 1 year

    There is a leak in my app and I am not sure where it comes from. I am using Leak Canary to trace the leak but still cannot pinpoint the exact cause.

    Any fresh suggestions how to approach the issue will be appreciated!

    This the leak from Leak Canary:

    ┬───
    │ GC Root: Global variable in native code
    │
    ├─ android.database.ContentObserver$Transport instance
    │    Leaking: UNKNOWN
    │    Retaining 85 B in 4 objects
    │    ↓ ContentObserver$Transport.mContentObserver
    │                                ~~~~~~~~~~~~~~~~
    ├─ io.flutter.view.AccessibilityBridge$3 instance
    │    Leaking: UNKNOWN
    │    Retaining 57 B in 3 objects
    │    Anonymous subclass of android.database.ContentObserver
    │    ↓ AccessibilityBridge$3.this$0
    │                            ~~~~~~
    ├─ io.flutter.view.AccessibilityBridge instance
    │    Leaking: UNKNOWN
    │    Retaining 626 B in 16 objects
    │    ↓ AccessibilityBridge.accessibilityChannel
    │                          ~~~~~~~~~~~~~~~~~~~~
    ├─ io.flutter.embedding.engine.systemchannels.AccessibilityChannel instance
    │    Leaking: UNKNOWN
    │    Retaining 24 B in 1 objects
    │    ↓ AccessibilityChannel.flutterJNI
    │                           ~~~~~~~~~~
    ├─ io.flutter.embedding.engine.FlutterJNI instance
    │    Leaking: UNKNOWN
    │    Retaining 144 B in 10 objects
    │    ↓ FlutterJNI.platformMessageHandler
    │                 ~~~~~~~~~~~~~~~~~~~~~~
    ├─ io.flutter.embedding.engine.dart.DartMessenger instance
    │    Leaking: UNKNOWN
    │    Retaining 8.0 kB in 113 objects
    │    ↓ DartMessenger.messageHandlers
    │                    ~~~~~~~~~~~~~~~
    ├─ java.util.HashMap instance
    │    Leaking: UNKNOWN
    │    Retaining 7.9 kB in 110 objects
    │    ↓ HashMap.table
    │              ~~~~~
    ├─ java.util.HashMap$Node[] array
    │    Leaking: UNKNOWN
    │    Retaining 7.8 kB in 109 objects
    │    ↓ HashMap$Node[].[7]
    │                     ~~~
    ├─ java.util.HashMap$Node instance
    │    Leaking: UNKNOWN
    │    Retaining 6.8 kB in 67 objects
    │    ↓ HashMap$Node.next
    │                   ~~~~
    ├─ java.util.HashMap$Node instance
    │    Leaking: UNKNOWN
    │    Retaining 6.8 kB in 65 objects
    │    ↓ HashMap$Node.value
    │                   ~~~~~
    ├─ io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler instance
    │    Leaking: UNKNOWN
    │    Retaining 6.7 kB in 62 objects
    │    ↓ MethodChannel$IncomingMethodCallHandler.handler
    │                                              ~~~~~~~
    ├─ io.github.ponnamkarthik.toast.fluttertoast.MethodCallHandlerImpl instance
    │    Leaking: UNKNOWN
    │    Retaining 6.7 kB in 61 objects
    │    context instance of com.example.app.Application
    │    ↓ MethodCallHandlerImpl.mToast
    │                            ~~~~~~
    ├─ android.widget.Toast instance
    │    Leaking: YES (This toast is done showing (Toast.mTN.mWM != null && Toast.
    │    mTN.mView == null))
    │    Retaining 6.7 kB in 60 objects
    │    mContext instance of com.example.app.Application
    │    ↓ Toast.mNextView
    ╰→ android.widget.FrameLayout instance
    ​     Leaking: YES (ObjectWatcher was watching this because android.widget.
    ​     FrameLayout received View#onDetachedFromWindow() callback)
    ​     Retaining 6.3 kB in 54 objects
    ​     key = f2d26abf-ece1-4929-b7bd-bb66cd4a300b
    ​     watchDurationMillis = 68439
    ​     retainedDurationMillis = 63437
    ​     View not part of a window view hierarchy
    ​     View.mAttachInfo is null (view detached)
    ​     View.mWindowAttachCount = 1
    ​     mContext instance of com.example.app.Application
    

    The chain of events leading to the leak seems to start on couple of different processes but Leak Canary always ends up detecting the same leak in Toast and FrameLayout.