You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello guys. I have been trying to resolve one issue with memory leak in ViewPager2.
So, I have:
MainActivity - here I initialize the views and setup Navigation component to navigate using bottom navigation view.
HomeFragment and Profile Fragment
In HomeFragment I have ViewPager2
TestFragment is a fragemnt that represents each viewPager's page
Iam using FragmentStateAdapter(fragmentManager, lifecycle) to create an adapter for my ViewPager2
I am getting a memory leak when I am navigating between my fragments in ViewPager2. I can't understand why I am getting the leak.
The Log:
`D/LeakCanary:
====================================
HEAP ANALYSIS RESULT
====================================
1 APPLICATION LEAKS
References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
6126 bytes retained by leaking objects
Displaying only 1 leak trace out of 3 with the same signature
Signature: f3295dce470d2cb483f6ce0a93abe2c145e0d996
┬───
│ 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 (ViewPager2$RecyclerViewImpl↓ is not leaking and 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.konda.viewpagertest.
│ MainActivity with mDestroyed = false
│ ↓ View.mAttachInfo
├─ android.view.View$AttachInfo instance
│ Leaking: NO (ViewPager2$RecyclerViewImpl↓ is not leaking)
│ ↓ View$AttachInfo.mScrollContainers
├─ java.util.ArrayList instance
│ Leaking: NO (ViewPager2$RecyclerViewImpl↓ is not leaking)
│ ↓ ArrayList[0]
├─ androidx.viewpager2.widget.ViewPager2$RecyclerViewImpl instance
│ Leaking: NO (View attached)
│ View is part of a window view hierarchy
│ View.mAttachInfo is not null (view attached)
│ View.mID = R.id.null
│ View.mWindowAttachCount = 1
│ mContext instance of com.konda.viewpagertest.MainActivity with mDestroyed = false
│ ↓ RecyclerView.mAdapter
│ ~~~~~~~~
├─ com.konda.viewpagertest.adapters.RadioStationFragmentAdapter instance
│ Leaking: UNKNOWN
│ Retaining 10,0 kB in 343 objects
│ ↓ RadioStationFragmentAdapter.hashMap
│ ~~~~~~~
├─ java.util.HashMap instance
│ Leaking: UNKNOWN
│ Retaining 6,5 kB in 220 objects
│ ↓ HashMap[instance @1898466120 of java.lang.Integer]
│ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
╰→ com.konda.viewpagertest.ui.TestFragment instance
Leaking: YES (ObjectWatcher was watching this because com.konda.viewpagertest.ui.TestFragment received
Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
Retaining 2,0 kB in 69 objects
key = ef189c4d-bb87-4f4f-b30c-3d31f5ede56b
watchDurationMillis = 54122
retainedDurationMillis = 49122
====================================`
private val hashMap = HashMap<Int, Fragment>()
override fun getItemCount(): Int = if (data.isNotEmpty()) Int.MAX_VALUE / 6 else 0
override fun createFragment(position: Int): Fragment {
when(position % data!!.size){
0 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag);
return mFrag
}
1 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag);
return mFrag
}
2 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag);
return mFrag
}
3 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag);
return mFrag
}
4 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag)
return mFrag
}
5 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag);
return mFrag
}
6 -> {
val mFrag = TestFragment()
hashMap.put(position, mFrag);
return mFrag
}
}
return Fragment()
}
}
`
TestFragment
`
class TestFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_test, container, false)
}
override fun onResume() {
super.onResume()
Log.e("TAG", "RESUME")
}
override fun onDestroyView() {
super.onDestroyView()
}
}`
Does anyone have an idea how this can be fixed? I want to avoid memory leaks in code, espcially working with primitive views like viewPager. I would be glad for any suggestion.
The text was updated successfully, but these errors were encountered:
Hello guys. I have been trying to resolve one issue with memory leak in ViewPager2.
So, I have:
Iam using FragmentStateAdapter(fragmentManager, lifecycle) to create an adapter for my ViewPager2
I am getting a memory leak when I am navigating between my fragments in ViewPager2. I can't understand why I am getting the leak.
The Log:
`D/LeakCanary:
====================================
HEAP ANALYSIS RESULT
====================================
1 APPLICATION LEAKS
CODE
HomeFragment
`override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
FragmentStateAdapter
`
class RadioStationFragmentAdapter(var data: ArrayList, fragmentManager: FragmentManager, lifecycle: Lifecycle): FragmentStateAdapter(fragmentManager, lifecycle) {
}
`
TestFragment
`
class TestFragment : Fragment() {
}`
Does anyone have an idea how this can be fixed? I want to avoid memory leaks in code, espcially working with primitive views like viewPager. I would be glad for any suggestion.
The text was updated successfully, but these errors were encountered: