MemoryLeak槽onConfigurationChanged() [英] MemoryLeak trough onConfigurationChanged()

查看:172
本文介绍了MemoryLeak槽onConfigurationChanged()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AsyncTask的,我需要重启,如果用户不配置,如开关颜色。

当他这样做,我开始AsyncTask的是这样的:

  myWorkerClass.clearMemory();
    myWorkerClass =新WorkerClass(getApplicationContext(),GV,搜索栏,宽度,scaleButtonText);
    myWorkerClass.execute();

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

要prevent MemoryLeaks我在我的AsyncTask的一个方法,删除 onTextChangedListener

 公共无效clearMemory(){
    sea​​rchbar.removeTextChangedListener(myTextWatcher);
}

除了当我转动我的设备一切正常。当我转动我的设备我只有这个做 onConfigurationChanged

  myWorkerClass.clearMemory();
            myWorkerClass =新WorkerClass(getApplicationContext(),GV,搜索栏,宽度,scaleButtonText);
            myWorkerClass.execute();

正如你可以看到我做同样的事情,如果用户更改了颜色。 但是是在在彩色切换旋转装置我正在泄漏内存,我不是!

这是切换后的颜色:

这就是旋转屏幕几次(记住后,我做的完全一样,在切换颜色:

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

这是我的支配树:

为什么我知道onTextChangeListener是什么问题?

因为如果我评论添加onTextChangedListener我的EditText出来,一切工作正常。没有内存泄漏。

我的问题:

为什么一个旋转变化内存泄漏和颜色变化不会当我开始的AsyncTask完全相同的方式和AsyncTask的范围内做确切同样的事情?

我搜索一点点: http://developer.android。 COM /引导/主题/资源/运行时changes.html

但我想不通,如果这是我的问题。自转必须做不同的事情,比如,因为,创造一个新的活动创造一个新的参考我的EditText。而且因为他不能删除旧的 onTextChangeListener

请理解。我不想让我的整个code公众。但我想反正这是没有必要在这种情况下。

我AP preciate任何帮助。

在此先感谢


解决方案

  

的轮换必须做不同的事情,比如因为,创造一个新的参考我的EditText创建一个新的活动。


确切地说,它会破坏你的当前活动,并创建一个新的。如果搜索栏是您的AsyncTask的成员变量然后再考虑将其放入了WeakReference:

 的WeakReference<搜索栏> sea​​rchbarPtr;

然后访问使用searchBarPtr.get(),但检查其是否为空,如果是的话那么就意味着它是垃圾回收,由于配置的改变。

也记得不要让你的AsyncTask的一个内部类,你的活动。如果是嵌套然后使它静态的。否则,你的AsyncTask将继续引用您的活动,它将prevent它被破坏 - 直到它的线头

Unfortuanately在所有情况下使所有工作corectly可以是相当困难和耗费时间。

希望没有人会通过Android的提示您的活动preventing破坏:configChanges,在旋转过程中实现您的活动正确的行为将prevent它崩溃/中不太常见的活动周期时刻不能为$ P泄漏由Android $ pvented:configChanges

i have an AsyncTask which i Need to "restart" if the user does configurations such as Switch Color.

When he do so i start the AsyncTask like this:

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

In the AsyncTask i add a onTextChangeListener to my EditText!(Which causes the MemoryLeak later).

To prevent MemoryLeaks i have a Method in my AsyncTask which removes the onTextChangedListener:

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

Everything works fine except when i rotate my device. When i rotate my Device i do only this in onConfigurationChanged:

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

As you can see i do exactly the same thing as if the user changes a Color. But at rotating device i'm leaking Memory, at switching Color i'm not!

This is after switching the Color:

This is after rotating the Screen a few times(remember i do exactly the same as at switching color:

These are my Leak Suspects from the Heap Dump:

This is my dominator tree:

Why do i know the onTextChangeListener is the Problem?

Because if i comment adding a onTextChangedListener to my EditText out, everything works fine. No Memory Leaks.

My Question:

Why does a Rotation Change leak Memory and a Color Change does not when i start the asynctask the exact same way and do exact the same things within the asynctask?

I searched a Little bit: http://developer.android.com/guide/topics/resources/runtime-changes.html

But i can't figure out if that is my Problem. The Rotation must do something different, like creating a new activity because of that creating a new reference to my edittext. And because of that he can't remove the old onTextChangeListener.

Please understand. I don't want to make my whole code public. But i think this isn't necessary anyway in this case.

I appreciate any help.

Thanks in advance

解决方案

The Rotation must do something different, like creating a new activity because of that creating a new reference to my edittext.

exactly, it destroys your current activity and creates a new one. If searchbar is a member variable of your AsyncTask then consider putting it into WeakReference:

WeakReference<SearchBar> searchbarPtr; 

then access using searchBarPtr.get(), but check if its null, if so then it means it was garbage collected due to config change.

Also remember to not make your AsyncTask an inner class of you activity. If it is nested then make it static. Otherwise your asynctask will keep reference to your activity and it will prevent it from being destroyed - until its thread ends.

Unfortuanately making it all work corectly in all situations can be quite difficult and time consuming.

Hopefully no one will suggest preventing destruction of your activity through android:configChanges, implementing correct behaviour of your activity during rotation will prevent it from crashing/leaking in less common activity lifecycle moments which cannot be prevented by android:configChanges.

这篇关于MemoryLeak槽onConfigurationChanged()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆