title: Leak Canary detects memory leaks for TabLayout with ViewPager2
body: <p>I followed the official documentation to setup a TabLayout with ViewPager2. I used the TabLayoutMediator this way to connect the TabLayout with the ViewPager2:</p>
  
  <pre><code>TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position -&gt;
          tab.setIcon(getTabIcon(position))
          tab.text = getTabTitle(position)
      }.attach()
  </code></pre>
  
  <p>However Leak Canary detects a memory leak that seems related to the TabLayout and the TabLayoutMediator. The log is the following:</p>
  
  <pre><code>2020-05-13 17:57:32.914 D/LeakCanary: ┬───
  2020-05-13 17:57:32.914 D/LeakCanary: │ GC Root: Local variable in native code
  2020-05-13 17:57:32.914 D/LeakCanary: │
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ android.net.ConnectivityThread instance
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (PathClassLoader↓ is not leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    Thread name: 'ConnectivityThread'
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ ConnectivityThread.contextClassLoader
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ dalvik.system.PathClassLoader instance
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (ViewDataBinding↓ is not leaking and A ClassLoader is never leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ PathClassLoader.runtimeInternalObjects
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ java.lang.Object[] array
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (ViewDataBinding↓ is not leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ Object[].[349]
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ androidx.databinding.ViewDataBinding class
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (RouteInfoFragment↓ is not leaking and a class is never leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ static ViewDataBinding.sReferenceQueue
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ java.lang.ref.ReferenceQueue instance
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (RouteInfoFragment↓ is not leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ ReferenceQueue.head
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ androidx.databinding.ViewDataBinding$WeakListener instance
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (RouteInfoFragment↓ is not leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ ViewDataBinding$WeakListener.mObservable
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ androidx.databinding.ViewDataBinding$LiveDataListener instance
  2020-05-13 17:57:32.914 D/LeakCanary: │    Leaking: NO (RouteInfoFragment↓ is not leaking)
  2020-05-13 17:57:32.914 D/LeakCanary: │    ↓ ViewDataBinding$LiveDataListener.mLifecycleOwner
  2020-05-13 17:57:32.914 D/LeakCanary: ├─ iclaude.berlinwanderer.features.route.ui.route_dashboard.route_info.RouteInfoFragment instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: NO (RouteDashboardFragment↓ is not leaking and Fragment#mFragmentManager is not null)
  2020-05-13 17:57:32.915 D/LeakCanary: │    Fragment.mTag=f0
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ RouteInfoFragment.mParentFragment
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ iclaude.berlinwanderer.features.route.ui.route_dashboard.RouteDashboardFragment instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: NO (Fragment#mFragmentManager is not null)
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ RouteDashboardFragment.mLifecycleRegistry
  2020-05-13 17:57:32.915 D/LeakCanary: │                             ~~~~~~~~~~~~~~~~~~
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ androidx.lifecycle.LifecycleRegistry instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ LifecycleRegistry.mObserverMap
  2020-05-13 17:57:32.915 D/LeakCanary: │                        ~~~~~~~~~~~~
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ androidx.arch.core.internal.FastSafeIterableMap instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ FastSafeIterableMap.mHashMap
  2020-05-13 17:57:32.915 D/LeakCanary: │                          ~~~~~~~~
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ java.util.HashMap instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ HashMap.table
  2020-05-13 17:57:32.915 D/LeakCanary: │              ~~~~~
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ java.util.HashMap$Node[] array
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ HashMap$Node[].[1]
  2020-05-13 17:57:32.915 D/LeakCanary: │                     ~~~
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ java.util.HashMap$Node instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ HashMap$Node.key
  2020-05-13 17:57:32.915 D/LeakCanary: │                   ~~~
  2020-05-13 17:57:32.915 D/LeakCanary: ├─ androidx.viewpager2.adapter.FragmentStateAdapter$5 instance
  2020-05-13 17:57:32.915 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.915 D/LeakCanary: │    Anonymous class implementing androidx.lifecycle.LifecycleEventObserver
  2020-05-13 17:57:32.915 D/LeakCanary: │    ↓ FragmentStateAdapter$5.this$0
  2020-05-13 17:57:32.916 D/LeakCanary: │                             ~~~~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ iclaude.berlinwanderer.features.route.ui.route_dashboard.RouteDashboardViewPagerAdapter instance
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ RouteDashboardViewPagerAdapter.mObservable
  2020-05-13 17:57:32.916 D/LeakCanary: │                                     ~~~~~~~~~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ androidx.recyclerview.widget.RecyclerView$AdapterDataObservable instance
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ RecyclerView$AdapterDataObservable.mObservers
  2020-05-13 17:57:32.916 D/LeakCanary: │                                         ~~~~~~~~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ java.util.ArrayList instance
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ ArrayList.elementData
  2020-05-13 17:57:32.916 D/LeakCanary: │                ~~~~~~~~~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ java.lang.Object[] array
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ Object[].[0]
  2020-05-13 17:57:32.916 D/LeakCanary: │               ~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ com.google.android.material.tabs.TabLayoutMediator$PagerAdapterObserver instance
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ TabLayoutMediator$PagerAdapterObserver.this$0
  2020-05-13 17:57:32.916 D/LeakCanary: │                                             ~~~~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ com.google.android.material.tabs.TabLayoutMediator instance
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: UNKNOWN
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ TabLayoutMediator.tabLayout
  2020-05-13 17:57:32.916 D/LeakCanary: │                        ~~~~~~~~~
  2020-05-13 17:57:32.916 D/LeakCanary: ├─ com.google.android.material.tabs.TabLayout instance
  2020-05-13 17:57:32.916 D/LeakCanary: │    Leaking: YES (View detached and has parent)
  2020-05-13 17:57:32.916 D/LeakCanary: │    mContext instance of iclaude.berlinwanderer.features.route.ui.RouteActivity with mDestroyed = false
  2020-05-13 17:57:32.916 D/LeakCanary: │    View#mParent is set
  2020-05-13 17:57:32.916 D/LeakCanary: │    View#mAttachInfo is null (view detached)
  2020-05-13 17:57:32.916 D/LeakCanary: │    View.mID = R.id.tab_layout
  2020-05-13 17:57:32.916 D/LeakCanary: │    View.mWindowAttachCount = 1
  2020-05-13 17:57:32.916 D/LeakCanary: │    ↓ TabLayout.mParent
  2020-05-13 17:57:32.916 D/LeakCanary: ╰→ androidx.constraintlayout.motion.widget.MotionLayout instance
  2020-05-13 17:57:32.916 D/LeakCanary: ​     Leaking: YES (ObjectWatcher was watching this because iclaude.berlinwanderer.features.route.ui.route_dashboard.RouteDashboardFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks))
  2020-05-13 17:57:32.916 D/LeakCanary: ​     key = 9c28ffc6-b1ce-4316-b015-c4df278892a1
  2020-05-13 17:57:32.916 D/LeakCanary: ​     watchDurationMillis = 36154
  2020-05-13 17:57:32.916 D/LeakCanary: ​     retainedDurationMillis = 31130
  2020-05-13 17:57:32.916 D/LeakCanary: ​     mContext instance of iclaude.berlinwanderer.features.route.ui.RouteActivity with mDestroyed = false
  2020-05-13 17:57:32.917 D/LeakCanary: ​     View#mParent is null
  2020-05-13 17:57:32.917 D/LeakCanary: ​     View#mAttachInfo is null (view detached)
  2020-05-13 17:57:32.917 D/LeakCanary: ​     View.mID = R.id.ml_main
  2020-05-13 17:57:32.917 D/LeakCanary: ​     View.mWindowAttachCount = 1
  </code></pre>
  
  <p>What's the problem? How to solve?</p>