从Android视图中删除所有监听器

4
为了避免内存泄漏,我想要从 Android 视图中移除所有的监听器和观察者。对于 TextWatcher,我知道需要将每个使用 addTextChangedListener() 添加的引用保存在数据结构中,并在 onDestroy 时使用 removeTextChangedListener() 进行移除。但对于视图的其他监听器,是否有一种方法可以找到它们并将它们设置为 null 呢?
到目前为止,在我的大多数视图上(EDIT: 所有已分配任何监听器的视图;根据情况,在 onDestroy() 和/或 onDestroyView() 中调用此方法):
 public static  void releaseView(View view){
        if(view != null ){
            view.removeCallbacks(null);
            if(!(view instanceof AdapterView)) {
                view.setOnClickListener(null);
                view.setOnTouchListener(null);
                view.setOnLongClickListener(null);
                view.setOnDragListener(null);
                view.setOnFocusChangeListener(null);
                view.setOnKeyListener(null);

                if (view instanceof TextView) {
                    ((TextView) view).setOnEditorActionListener(null);
                    ((TextView) view).setKeyListener(null);


                    if(view instanceof CheckBox)
                        ((CheckBox) view).setOnCheckedChangeListener(null);
                }
            }
            else {
                if (view instanceof ListView) {
                    ((ListView) view).setOnItemClickListener(null);
                    ((ListView) view).setOnItemLongClickListener(null);
                    ((ListView) view).setOnItemSelectedListener(null);
                    ((ListView) view).setOnScrollListener(null);
                    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) //if Marshamallow => API 23
                        ((ListView) view).setOnScrollChangeListener(null);
                    ((ListView) view).setAdapter(null);
                    //return;
                }

                if (view instanceof Spinner) {
                    ((Spinner) view).setOnItemSelectedListener(null);
                    //return;
                }

                if (view instanceof GridView) {
                    ((GridView) view).setOnItemSelectedListener(null);
                    ((GridView) view).setAdapter(null);                       
                }
            }          
        }
    } 

然而,我仍然会得到一些被此方法调用的视图泄漏的问题。是否有什么我遗漏的地方?如果我犯了错误,请有人指出。


你能提供一下可疑内存泄漏的堆栈跟踪吗?因为在Android中,所有视图几乎都没有关联任何监听器。 - Maddy Blacklisted
@Maddy 在 Android 中,每次为视图分配侦听器时,您都必须将其清除(将该侦听器设置为 null),以避免任何内存泄漏。 - Maxime Claude
2个回答

0
在Android中,几乎所有视图中的监听器默认情况下都是null,除非您初始化任何一个。
因此,设置为null是绝对不必要的
为什么您认为存在内存泄漏?是否有任何错误日志?

我会在每个被分配了监听器的视图上调用此方法。当它在Activity中时,它在onDestroy()中被调用,而在Fragment中时,它在onDestroyView()中被调用。我认为这里有一个内存泄漏,因为在Java堆转储中有迹象。 - Maxime Claude

0

通常情况下,监听器不会导致任何内存泄漏除非您以某种不正确的方式创建或操纵它们,以创建内存中的任何循环引用或环状引用。更多信息可以在这里找到!

如果您正确创建和/或使用监听器,则无需不必要地删除监听器。

进一步建议阅读《官方 Android 文档:避免内存泄漏》获取更多帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接