When I open my fragment that used data binding, memory leak occur as shown in below. Is there any appropriate answer to solve this?
I used
- Data binding
- Navigation
- Lifecycle
- Material ui
┬───
│ GC Root: System class
│
├─ androidx.databinding.ViewDataBinding class
│ Leaking: NO (a class is never leaking)
│ ↓ static ViewDataBinding.sReferenceQueue
│ ~~~~~~~~~~~~~~~
├─ java.lang.ref.ReferenceQueue instance
│ Leaking: UNKNOWN
│ ↓ ReferenceQueue.head
│ ~~~~
├─ androidx.databinding.ViewDataBinding$WeakListener instance
│ Leaking: UNKNOWN
│ ↓ ViewDataBinding$WeakListener.mObservable
│ ~~~~~~~~~~~
├─ androidx.databinding.ViewDataBinding$LiveDataListener instance
│ Leaking: UNKNOWN
│ ↓ ViewDataBinding$LiveDataListener.mLifecycleOwner
│ ~~~~~~~~~~~~~~~
╰→ com.norm.news.ui.source.NewsSourceFragment instance
Leaking: YES (ObjectWatcher was watching this because com.norm.news.ui.source.NewsSourceFragment received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
key = 55b68d7d-56bb-46ff-ad17-e29f01b6a808
watchDurationMillis = 5207
retainedDurationMillis = 139
key = 2fc4bd04-641e-4bea-8e13-71650f6e2a25
METADATA
Build.VERSION.SDK_INT: 24
Build.MANUFACTURER: samsung
LeakCanary version: 2.1
App process name: com.norm.news.debug
Analysis duration: 12283 ms
Here is a snippet code in my fragment.
This code is referenced from Android Kotlin Fundamentals 05.3: Data binding with ViewModel and LiveData
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentNewsSourceBinding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_news_source,
container,
false
)
// Specify the current activity as the lifecycle owner of the binding.
// This is necessary so that the binding can observe LiveData updates.
binding.lifecycleOwner = this
val application = requireNotNull(this.activity).application
val viewModelFactory = NewsSourceViewModelFactory(application)
val newsSourceViewModel =
ViewModelProviders.of(this, viewModelFactory).get(NewsSourceViewModel::class.java)
binding.newsSourceViewModel = newsSourceViewModel
binding.rvSourceLists.adapter = NewsSourceAdapter(NewsSourceAdapter.OnClickListener {
newsSourceViewModel.displayNewsSourceDetails(it)
})
newsSourceViewModel.navigateToSelectedItem.observe(viewLifecycleOwner, Observer {
if (it != null) {
this.findNavController()
.navigate(NewsSourceFragmentDirections.actionNewsSourceFragmentToNewsFragment(it.id))
newsSourceViewModel.displayNewsSourceDetailsComplete()
}
})
return binding.root
}