内存泄漏与setOnClickListener(this)和setOnClickListener(new View.OnClickListener(){})

时间:2012-09-23 13:10:14

标签: android memory-leaks

我读到了avoiding memory leaks

要避免与上下文相关的内存泄漏,请记住以下内容:

  • 尝试使用context-application代替context-activity

我有两个问题:

  1. 如果我使用setOnClickListener(this),会导致内存泄漏吗?
  2. 如果我使用setOnClickListener(new View.OnClickListener(){}),会导致内存泄漏吗?

3 个答案:

答案 0 :(得分:0)

我会说你可以同时使用两者。虽然,如果您有多个按钮(或任何其他小部件),最好使用第一个解决方案和getId()来区分它们,第二个解决方案为每个按钮创建一个不同的侦听器(对象),因此它会保留更多内存。我不认为它们中的任何一个会导致内存泄漏,因为当你销毁一个活动,并且没有留下任何链接时,java GC会将该内存(监听器对象)返回给dalvik。

希望它有所帮助:)

答案 1 :(得分:0)

1-如果我使用setOnClickListener(this),会导致内存泄漏吗?

不是必需的,“ this”实现OnClickListener,如果您不泄漏自己的信息,例如在 onClick 中运行线程将泄漏,使用非静态内部类将泄漏,因此答案是setOnClickListener(this)仅在您的 onClick(View view)实现泄漏时泄漏。

2-如果我使用setOnClickListener(new View.OnClickListener(){}),会导致内存泄漏吗?

是相同的问题,取决于您为OnClickListener.onClick实现了什么...不要泄漏您实现 new View.OnclickListener ....的类,那么您会没事的。

答案 2 :(得分:0)

这可能有点晚了,但是我想将其添加到上面的答案中:它取决于您在OnClickListener中的操作,假设您引用的是片段的父级活动并且您正在为片段内的视图设置此OnClickListener,则可能需要删除引用,否则可能会泄漏内存:

onSettingsHeaderMenuItemClickedListener = View.OnClickListener {
            GuidedStepSupportFragment.add(requireActivity().supportFragmentManager, SettingsFragment.newInstance(), android.R.id.content)
}

例如,上面的代码在父活动中引用片段管理器,并且发生在一个片段中,因此必须清除该引用,否则它将泄漏整个活动和片段!

我更喜欢使用可以从Google architecture components sample中选择的autoCleared委托来解决此问题。

因此,点击侦听器在片段中且需要活动引用时的整个实现将类似于以下代码:

    class SomeFragment{
        private var onSettingsHeaderMenuItemClickedListener by autoCleared<View.OnClickListener>()
        fun onViewCreated(){
            onSomethingItemClickedListener = View.OnClickListener {
                GuidedStepSupportFragment.add(requireActivity().supportFragmentManager, SettingsFragment.newInstance(), android.R.id.content)
            }
            findViewById<View>(R.id.header_item_settings).setOnClickListener(onSettingsHeaderMenuItemClickedListener)
        }
    }