question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Snackbar] Memory leak due to setAnchorView

See original GitHub issue

Description: Anchoring works as expected but, the listener is never removed and LeakCanary is getting a memory leak

Expected behavior: It’s working as expected, SnackBar is shown above the desired view. But there is a Memory leak, I tried referencing via IdRes, view from ViewBinding, view from findViewById, always the same. When I remove setAnchroView there is no leak. I think it’s connected with ViewUtils.addOnGlobalLayoutListener in setAnchorView function of BaseTransientBottomBar, its never removed after showing

Source code:

with(viewBinding.venueRecyclerView) {
                    Snackbar
                        .make(
                            viewBinding.root,
                            context.getString(R.string.tap_again_in_map_venue),
                            Snackbar.LENGTH_SHORT
                        )
                        .setAnchorView(this)
                        .show()
                }

Leak canary :

┬───
 β”‚ GC Root: System class
 β”‚
 β”œβ”€ android.view.inputmethod.InputMethodManager class
 β”‚    Leaking: NO (InputMethodManager↓ is not leaking and a class is never leaking)
 β”‚    ↓ static InputMethodManager.sInstance
 β”œβ”€ android.view.inputmethod.InputMethodManager instance
 β”‚    Leaking: NO (DecorView↓ is not leaking and InputMethodManager is a singleton)
 β”‚    ↓ InputMethodManager.mCurRootView
 β”œβ”€ com.android.internal.policy.DecorView instance
 β”‚    Leaking: NO (View attached)
 β”‚    View is part of a window view hierarchy
 β”‚    View.mAttachInfo is not null (view attached)
 β”‚    View.mWindowAttachCount = 1
 β”‚    mContext instance of com.android.internal.policy.DecorContext, wrapping activity com.upgrades.venue.user.
 β”‚    presentation.MainActivity with mDestroyed = false
 β”‚    ↓ View.mAttachInfo
 β”‚           ~~~~~~~~~~~
 β”œβ”€ android.view.View$AttachInfo instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.4 MB in 13380 objects
 β”‚    ↓ View$AttachInfo.mTreeObserver
 β”‚                      ~~~~~~~~~~~~~
 β”œβ”€ android.view.ViewTreeObserver instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.4 MB in 13337 objects
 β”‚    ↓ ViewTreeObserver.mOnGlobalLayoutListeners
 β”‚                       ~~~~~~~~~~~~~~~~~~~~~~~~
 β”œβ”€ android.view.ViewTreeObserver$CopyOnWriteArray instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.1 MB in 13264 objects
 β”‚    ↓ ViewTreeObserver$CopyOnWriteArray.mData
 β”‚                                        ~~~~~
 β”œβ”€ java.util.ArrayList instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.1 MB in 13262 objects
 β”‚    ↓ ArrayList.elementData
 β”‚                ~~~~~~~~~~~
 β”œβ”€ java.lang.Object[] array
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.1 MB in 13261 objects
 β”‚    ↓ Object[].[0]
 β”‚               ~~~
 β”œβ”€ com.google.android.material.snackbar.BaseTransientBottomBar$2 instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.1 MB in 13260 objects
 β”‚    Anonymous class implementing android.view.ViewTreeObserver$OnGlobalLayoutListener
 β”‚    ↓ BaseTransientBottomBar$2.this$0
 β”‚                               ~~~~~~
 β”œβ”€ com.google.android.material.snackbar.Snackbar instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.1 MB in 13259 objects
 β”‚    context instance of com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
 β”‚    ↓ BaseTransientBottomBar.anchorView
 β”‚                             ~~~~~~~~~~
 β”œβ”€ androidx.recyclerview.widget.RecyclerView instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 2.1 MB in 13011 objects
 β”‚    View not part of a window view hierarchy
 β”‚    View.mAttachInfo is null (view detached)
 β”‚    View.mID = R.id.venue_recycler_view
 β”‚    View.mWindowAttachCount = 1
 β”‚    mContext instance of dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper, wrapping
 β”‚    activity com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
 β”‚    ↓ View.mContext
 β”‚           ~~~~~~~~
 β”œβ”€ dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper instance
 β”‚    Leaking: UNKNOWN
 β”‚    Retaining 172 B in 6 objects
 β”‚    mBase instance of com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
 β”‚    ViewComponentManager$FragmentContextWrapper wraps an Activity with Activity.mDestroyed false
 β”‚    ↓ ViewComponentManager$FragmentContextWrapper.fragment
 β”‚                                                  ~~~~~~~~
 β•°β†’ com.upgrades.venue.user.presentation.explore.ExploreMapFragment instance
 ​     Leaking: YES (ObjectWatcher was watching this because com.upgrades.venue.user.presentation.explore.
 ​     ExploreMapFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
 ​     Retaining 1.9 MB in 10078 objects
 ​     key = 90d80d2a-9c93-4a64-960a-5925009d3547
 ​     watchDurationMillis = 199061
 ​     retainedDurationMillis = 194060
 ​     componentContext instance of dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper,
 ​     wrapping activity com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
 ​     uiController instance of com.upgrades.venue.user.presentation.MainActivity with mDestroyed = false
 2807 bytes retained by leaking objects
 Signature: e3e5b03a4f9b45443e8991fe4237eb4ebee6defa

Android API version: Any

Material Library version: Material Android Library version 1.3.0-rc01

Device: 2 emulators Pixel 2 and Pixel C, and Huawei mate 20 lite

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:9
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
drchencommented, Jun 18, 2021

The issue has been fixed for most of the cases except for one - when the snackbar is still showing but the anchor view is detached. We are figuring out a more comprehensive fix here.

1reaction
bryn-hardingcommented, Jun 18, 2021

We hit this issue and worked around it by keeping a reference to the Snackbar and setting the anchorView back to null when our Activity’s onDestroy() is called. This removes the OnGlobalLayoutListener for the original anchorView and removes the leak.

Looking at the code for setAnchorView() you can see that it first removes the existing OnGlobalLayoutListener and then adds a new one. However, because we call it with null, a new one doesn’t get added as there’s a null check in ViewUtils.addOnGlobalLayoutListener()

Read more comments on GitHub >

github_iconTop Results From Across the Web

Memory Leak due to Snackbar - Stack Overflow
IΒ΄m creating a Snackbar in the onCreateView and set it to null in onDestroyView . However I get a memory leak every time...
Read more >
Preventing and detecting memory leaks in Android apps
Memory leaks can cause your Android app to crash, causing frustration and lower usage. Learn how to fix them in this guide.
Read more >
Memory Leak Due To Snackbar - ADocLib
A Snackbar is a widget that looks like a small banner that pops up at the bottom ... 1 ListView and GridView's item...
Read more >
Memory Leaks in Android: Find, Fix, and Avoid
1. You should not: Avoid using static variables for views or context-related references. Pass a context-related reference to a Singleton class. Improperly use...
Read more >
[Snackbar] setAnchorView() for BottomNavigationView does ...
setAnchorView () to show the Snackbar above the BottomNavigationView. However, Snackbar does ... Possible memory leak in 2.1.210, 5, 2022-04-02, 2022-09-29.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found