我有一个AsyncTask,我需要“重新启动”,如果用户做的配置,如开关颜色。
当他这样做时,我会像这样启动AsyncTask:
myWorkerClass.clearMemory();
myWorkerClass = new WorkerClass(getApplicationContext(), gv, searchbar, width, scaleButtonText);
myWorkerClass.execute();在AsyncTask中,我将一个onTextChangeListener添加到我的EditText!(这会导致稍后的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 out中,一切都会很好。没有内存泄漏。
我的问题:
为什么当我以完全相同的方式启动异步任务并在异步任务中执行相同的事情时,旋转更改会泄漏内存,而颜色的变化不会发生呢?
我搜索了一点:http://developer.android.com/guide/topics/resources/runtime-changes.html
但我不知道这是不是我的问题。轮转必须做一些不同的事情,比如创建一个新的活动,因为这样创建了对我的编辑文本的新引用。正因为如此,他无法移除旧的onTextChangeListener。
请理解。我不想公开我的全部代码。但我觉得这在这种情况下是没有必要的。
发布于 2014-12-12 00:57:09
轮转必须做一些不同的事情,比如创建一个新的活动,因为这样创建了对我的编辑文本的新引用。
确切地说,它破坏了您当前的活动并创建了一个新的活动。如果searchbar是AsyncTask的成员变量,那么考虑将其放入WeakReference中:
WeakReference<SearchBar> searchbarPtr; 然后使用searchBarPtr.get()进行访问,但是检查它是否为null,如果为null,则意味着它由于配置更改而被垃圾收集。
还请记住,不要让AsyncTask成为您活动的内部类。如果它是嵌套的,那么使它是静态的。否则,异步任务将保持对活动的引用,并将防止其被销毁-直到线程结束。
不巧的是,在所有的情况下,让所有的事情都能顺利地完成是非常困难的,也是很费时的。
希望没有人会建议防止通过android:configChanges破坏您的活动,在旋转过程中实现正确的活动行为将防止它在不太常见的活动生命周期中崩溃/泄漏,而android:configChanges是无法阻止的。
发布于 2014-12-12 07:02:18
在android中,旋转会破坏您当前的活动,从而启动一个新的活动。
为了避免这种情况,可以在清单文件中添加android:configChanges="orientation|screenSize"。
以下是避免旋转更改时内存泄漏的提示
来源:避免内存泄漏
https://stackoverflow.com/questions/27435134
复制相似问题