内存泄漏通过onConfigurationChanged()

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存泄漏通过onConfigurationChanged()相关的知识,希望对你有一定的参考价值。

我有一个AsyncTask,如果用户执行Switch Color等配置,我需要“重启”。

当他这样做时,我就像这样启动AsyncTask:

myWorkerClass.clearMemory();
    myWorkerClass = new WorkerClass(getApplicationContext(), gv, searchbar, width, scaleButtonText);
    myWorkerClass.execute();

AsyncTask中,我在我的EditText中添加了一个onTextChangeListener!(后来导致MemoryLeak)。

为了防止MemoryLeaks我在我的AsyncTask中有一个方法,它删除了onTextChangedListener

public void clearMemory() {
    searchbar.removeTextChangedListener(myTextWatcher);
}

除非我旋转设备,否则一切正常。当我旋转我的设备时,我只在onConfigurationChanged中执行此操作:

myWorkerClass.clearMemory();
            myWorkerClass = new WorkerClass(getApplicationContext(), gv, searchbar, width, scaleButtonText);
            myWorkerClass.execute();

正如您所看到的,我做的事情与用户更改颜色完全相同。但是在旋转设备上我正在泄漏内存,在切换颜色时我不是!

这是在切换颜色后:

这是在旋转屏幕几次之后(记住我做的与切换颜色完全相同:

这些是我从堆转储泄漏的嫌疑人:

这是我的统治者树:

为什么我知道onTextChangeListener是问题?

因为如果我评论将onTextChangedListener添加到我的EditText中,一切正常。没有内存泄漏。

我的问题:

当我以完全相同的方式启动asynctask并且在asynctask中执行相同的操作时,为什么旋转更改泄漏内存和颜色更改不会?

我搜索了一下:http://developer.android.com/guide/topics/resources/runtime-changes.html

但我无法弄清楚这是不是我的问题。 Rotation必须做一些不同的事情,比如创建一个新的活动,因为它创建了一个对我的edittext的新引用。因此,他无法删除旧的onTextChangeListener

敬请谅解。我不想公开我的整个代码。但我认为在这种情况下无论如何都没有必要。

答案

Rotation必须做一些不同的事情,比如创建一个新的活动,因为它创建了一个对我的edittext的新引用。

确切地说,它会破坏您当前的活动并创建一个新的活动。如果searchbar是AsyncTask的成员变量,那么考虑将其放入WeakReference中:

WeakReference<SearchBar> searchbarPtr; 

然后使用searchBarPtr.get()进行访问,但检查它是否为null,如果是,则表示由于配置更改而被垃圾收集。

还记得不要让你的AsyncTask成为你活动的内部类。如果它是嵌套的,那么将其设置为静态。否则你的asynctask将继续引用你的活动,它将阻止它被销毁 - 直到它的线程结束。

不幸的是,在所有情况下使其全部正常工作可能非常困难且耗时。

希望没有人建议通过android:configChanges来防止你的活动被破坏,在轮换期间实现你的活动的正确行为将防止它在不太常见的活动生命周期中崩溃/泄漏,这是android:configChanges无法阻止的。

另一答案

在android中,旋转会破坏当前活动以启动新活动。 要避免它,您可以在清单文件中添加android:configChanges="orientation|screenSize"

以下是避免轮换更改时内存泄漏的提示

  1. 不要长期保持对上下文活动的引用(对活动的引用应该与活动本身具有相同的生命周期)
  2. 尝试使用context-application而不是context-activity
  3. 如果不控制生命周期,请避免活动中的非静态内部类,使用静态内部类并对内部活动进行弱引用。这个问题的解决方案是使用带有WeakReference的静态内部类到外部类,就像在ViewRoot及其W内部类中所做的那样
  4. 垃圾收集器不是防止内存泄漏的保险

资料来源:Avoiding memory leaks

以上是关于内存泄漏通过onConfigurationChanged()的主要内容,如果未能解决你的问题,请参考以下文章

C ++中的内存泄漏示例(通过使用异常)[重复]

内存泄漏检测

内存泄漏和内存溢出

内存泄漏检测

记一次Android内存泄漏的优化经历

内存泄漏(memory leak)和内存溢出