【发布时间】:2015-01-08 19:37:04
【问题描述】:
我有一个在主线程上声明的处理程序:
mainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Bundle bundle = msg.getData();
mTextView.setText(bundle.getString("message"));
break;
. . .
default:
super.handleMessage(msg);
break;
}
}
};
其中 mTextView 是定义 onCreate() 的 TextView。
我有一个在单独线程中使用的任务。 runnable 存储来自主线程的mainHandler 并告诉它发送消息:
public class SomeRunnable implements Runnable {
private Handler mHandler;
public SomeRunnable(Handler handler) throws IOException {
. . .
mHandler = handler;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
. . .
Message msg = mHandler.obtainMessage();
. . .
mHandler.sendMessage(msg);
}
} catch (IOException e) {
Log.e("Error", e.hashCode() + ": " + e.getLocalizedMessage());
}
}
}
我已经看到,如果 Handler 类不是静态的,则使用 Handler#postDelayed() 等方法可能会造成内存泄漏。但是,我使用的是Handler#sendMessage(),它会立即将一条消息放入消息队列中。
我还有内存泄漏的危险吗?即使有:
@Override
protected void onDestroy() {
super.onDestroy();
mThread.interrupt();
mainHandler.removeCallbacksAndMessages(null);
}
谢谢!
【问题讨论】:
-
从您发布的代码中不清楚,但您的
Handler或Runnable是否包含对非瞬态对象的任何引用?此外,与您似乎所说的相反,我希望staticly 持有Handler比我在上面看到的更容易发生内存泄漏。 -
@323go 我的 Runnable "SomeRunnable" 与主线程中的 Handler "mainHandler" 拥有相同的地址。这是你定义为非瞬态的吗?我的 Handler 没有任何引用,尽管它确实引用了主线程中的 TextView。
-
为了安全起见,您可以引用
mainHandler和WeakReference。否则看起来你会没事的。 -
Zack,如果你使用
eclipse,另一种方法是使用Eclipse Memory Analyzer。并查看您的Application是否泄漏内存,使用该工具您还可以确定导致程序泄漏的原因。见here -
@Mike 我今天早上才下载这个。感谢您的建议。我一定会尝试一下并分析内存。只是想我会问在概念上我的实现是否可能存在潜在的内存泄漏。
标签: java android memory-leaks