我有一个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
。
请理解。我不想公开我的整个代码。但我认为在这种情况下无论如何都没有必要。
答案 0 :(得分:0)
旋转必须做一些不同的事情,比如创建一个新的活动,因为它创建了一个对我的edittext的新引用。
确切地说,它会破坏您当前的活动并创建一个新的活动。如果searchbar
是AsyncTask的成员变量,那么考虑将其放入WeakReference:
WeakReference<SearchBar> searchbarPtr;
然后使用searchBarPtr.get()进行访问,但是检查它是否为null,如果是,则表示由于配置更改而被垃圾收集。
另外请记住不要让AsyncTask成为您活动的内部类。如果它是嵌套的,那么将其设置为静态。否则你的asynctask将继续引用你的活动,它将阻止它被销毁 - 直到它的线程结束。
在所有情况下,不可否认地使所有工作都非常困难和耗时。
希望没有人会建议通过android:configChanges来防止你的活动被破坏,在轮换期间实现你的活动的正确行为将防止它在不太常见的活动生命周期中崩溃/泄漏,这是android:configChanges无法阻止的。
答案 1 :(得分:0)
在android中,旋转会破坏您当前的活动以启动新活动
为避免这种情况,您可以在清单文件中添加android:configChanges="orientation|screenSize"
。
以下是避免轮换更改时内存泄漏的提示