首页 > 解决方案 > Android DataBinding 正在泄漏内存

问题描述

我正在使用数据绑定,并且我已经lateinit var为绑定声明了一个,当我要去不同的片段 Leaky canary 显示泄漏时。

分段

class HomeFragment : BottomNavViewHostBaseFragment() {

    private lateinit var viewModel: HomeViewModel
    private lateinit var binding: FragmentHomeBinding

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        viewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
        binding.lifecycleOwner = viewLifecycleOwner
        binding.viewModel = viewModel
        return binding.root
    }

   ...
}

这是来自 Leaky Carny 的信息

androidx.constraintlayout.widget.ConstraintLayout has leaked:
Toast$TN.mNextView
↳ LinearLayout.mContext
↳ MainActivity.navigationView
↳ NavigationView.listener
↳ BaseFragment$setNavigationDrawerItemSelectedListener$1.this$0 (anonymous implementation of com.google.android.material.navigation.NavigationView$OnNavigationItemSelectedListener) ↳ OrdersHostFragment.mFragmentManager
↳ FragmentManagerImpl.mActive
↳ HashMap.table
↳ array HashMap$HashMapEntry[].[0]
↳ HashMap$HashMapEntry.value
↳ HomeFragment.!(binding)!
↳ FragmentHomeBindingImpl.!(mboundView0)!
↳ ConstraintLayout

我该如何解决这个问题,我需要在binding=null里面做onDestroyView吗?但是,如果我需要这样做,那又有什么意义binding.lifecycleOwner = viewLifecycleOwner呢?

标签: androidkotlinandroid-databinding

解决方案


这是google docs推荐的在 Fragments 中初始化和清除绑定的方法:

科特林:

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

爪哇:

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater, 
                          ViewGroup container, 
                          Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

此外,这里是一篇中等博客文章,可以阅读以摆脱与 Property Delegate 的绑定内存泄漏。


推荐阅读