gpt4 book ai didi

android - 数据绑定(bind)内存泄漏

转载 作者:行者123 更新时间:2023-12-05 00:16:29 27 4
gpt4 key购买 nike

当我打开使用数据绑定(bind)的 fragment 时,发生内存泄漏,如下所示。有没有合适的答案来解决这个问题?

我用过

  • 数据绑定(bind)
  • 导航
  • 生命周期
  • Material 用户界面
┬───
│ 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

这是我的 fragment 中的一段代码。

此代码引用自 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
}

最佳答案

根据阅读泄漏跟踪和源代码,这看起来像是数据绑定(bind)库中的错误。我不确定是什么触发了它。

有一个引用队列,当弱引用的实例弱可达时,WeakListener 实例被添加到其中。所以我们知道这是在这种情况下监听器所处的状态。 WeakRefs enqueued 将留在那里,直到队列被消费代码(此处为数据绑定(bind)库)处理,这通常不是问题,因为 ref 为 null。然而这里的 weakref 有一个 mObservable 字段,它最终会泄漏一个生命周期所有者,它是一个被破坏的 fragment 。这将在接下来处理引用队列时停止泄漏,但不清楚何时发生。

所以这看起来像是数据绑定(bind)库如何处理弱引用的设计缺陷/错误。

您可能应该使用此上下文向该项目提交错误,并提供额外的详细信息,例如 lib 版本号。提供堆转储(易于从 leakcanary 共享)也会有所帮助。

关于android - 数据绑定(bind)内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59890559/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com