【问题标题】:Databinding memory-leak数据绑定内存泄漏
【发布时间】:2019-12-18 22:39:31
【问题描述】:

我使用 Jetpack 的导航来管理 Fragment,它在 Fragment 中使用数据绑定。

没有添加其他代码。 内存泄漏是HomeFragment.databinding.root,是一个LinearLayout,LinearLayout什么都没放。 LeakCanary 消息如下所示:

我使用 Jetpack 的导航来管理 Fragment,它在 Fragment 中使用数据绑定。

没有添加其他代码。 内存泄漏是HomeFragment.databinding.root,是一个LinearLayout,LinearLayout什么都没放。 LeakCanary 消息如下所示:

ApplicationLeak(className=android.widget.LinearLayout, leakTrace=
┬
├─ android.app.ActivityThread
│    Leaking: NO (ActivityThread↓ is not leaking and a class is never leaking)
│    GC Root: System class
│    ↓ static ActivityThread.sCurrentActivityThread
├─ android.app.ActivityThread
│    Leaking: NO (ArrayMap↓ is not leaking)
│    ↓ ActivityThread.mActivities
├─ android.util.ArrayMap
│    Leaking: NO (Object[]↓ is not leaking)
│    ↓ ArrayMap.mArray
├─ java.lang.Object[]
│    Leaking: NO (ActivityThread$ActivityClientRecord↓ is not leaking)
│    ↓ array Object[].[1]
├─ android.app.ActivityThread$ActivityClientRecord
│    Leaking: NO (MainActivity↓ is not leaking)
│    ↓ ActivityThread$ActivityClientRecord.activity
├─ com.ukex.module.index.ui.MainActivity
│    Leaking: NO (FragmentController↓ is not leaking and Activity#mDestroyed is false)
│    ↓ MainActivity.mFragments
├─ androidx.fragment.app.FragmentController
│    Leaking: NO (FragmentActivity$HostCallbacks↓ is not leaking)
│    ↓ FragmentController.mHost
├─ androidx.fragment.app.FragmentActivity$HostCallbacks
│    Leaking: NO (FragmentManagerImpl↓ is not leaking)
│    ↓ FragmentActivity$HostCallbacks.mFragmentManager
├─ androidx.fragment.app.FragmentManagerImpl
│    Leaking: NO (NavHostFragment↓ is not leaking)
│    ↓ FragmentManagerImpl.mPrimaryNav
├─ androidx.navigation.fragment.NavHostFragment
│    Leaking: NO (FragmentManagerImpl↓ is not leaking and Fragment#mFragmentManager is not null)
│    ↓ NavHostFragment.mChildFragmentManager
├─ androidx.fragment.app.FragmentManagerImpl
│    Leaking: NO (HashMap↓ is not leaking)
│    ↓ FragmentManagerImpl.mActive
├─ java.util.HashMap
│    Leaking: NO (HashMap$Node[]↓ is not leaking)
│    ↓ HashMap.table
├─ java.util.HashMap$Node[]
│    Leaking: NO (HashMap$Node↓ is not leaking)
│    ↓ array HashMap$Node[].[0]
├─ java.util.HashMap$Node
│    Leaking: NO (HomeFragment↓ is not leaking)
│    ↓ HashMap$Node.value
├─ com.ukex.module.index.ui.HomeFragment
│    Leaking: NO (Fragment#mFragmentManager is not null)
│    ↓ HomeFragment.dataBinding
│                   ~~~~~~~~~~~
├─ com.ukex.databinding.HomeFragmentBindingImpl
│    Leaking: UNKNOWN
│    ↓ HomeFragmentBindingImpl.mRoot
│                              ~~~~~
╰→ android.widget.LinearLayout
​     Leaking: YES (ObjectWatcher was watching this)
​     mContext instance of com.ukex.module.index.ui.MainActivity with mDestroyed = false
​     View#mParent is null
​     View#mAttachInfo is null (view detached)
​     View.mWindowAttachCount = 1
​     key = 965e1901-f293-454b-b8c2-80b869d64f9a
​     watchDurationMillis = 21809
​     retainedDurationMillis = 16807
, retainedHeapByteSize=6255)
class HomeFragment : BaseVMFragment<HomeViewModel>() {
    private lateinit var dataBinding: HomeFragmentBinding


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {


            dataBinding =
            DataBindingUtil.inflate(inflater, R.layout.home_fragment, container, false)
        return dataBinding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        dataBinding.apply {
            vm = mViewModel
            lifecycleOwner = this@HomeFragment
        }
        btnLogin.setOnClickListener {

            startActivity(Intent(context, LoginAct::class.java))
        }
    }


    override fun bindObserve() {
        super.bindObserve()
        mViewModel?.user?.observe(this, Observer {
            if (it != null)
                ToastUtils.showLong(it.username)
        })

    }

    override fun providerVMClass(): Class<HomeViewModel>? {
        return HomeViewModel::class.java
    }



}

【问题讨论】:

  • 信息不足,无法回答您的问题。请添加您的 HomeFragment
  • 抱歉,我没有删除它们。
  • 我只是根据您的要求修改了问题内容。

标签: android data-binding memory-leaks android-jetpack leakcanary


【解决方案1】:

在 Fragment.onDestroyView() 被调用后,视图应该从内存中释放,即使片段还没有被销毁。

您需要重写 HomeFragment.onDestroyView() 并将 dataBinding(或它包装的视图)设置为 null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-29
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    • 2022-07-14
    • 1970-01-01
    相关资源
    最近更新 更多