Reputation: 871
I have a Handler which is declared on the main thread:
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;
}
}
};
Where mTextView is a TextView defined onCreate().
I have a task which is used in a separate thread. The runnable stores mainHandler
from the main thread and tells it to send messages:
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());
}
}
}
I have seen that you can potentially create memory leaks by using methods such as Handler#postDelayed()
if the Handler class is not static. But, I am using Handler#sendMessage()
which instantly puts a Message in the message queue.
Am I still in danger of having a memory leak? Even with:
@Override
protected void onDestroy() {
super.onDestroy();
mThread.interrupt();
mainHandler.removeCallbacksAndMessages(null);
}
Thank you!
Upvotes: 1
Views: 940
Reputation: 14274
To address all eventualities, you could make mHandler
a WeakReference
as below:
public class SomeRunnable implements Runnable {
private WeakReference<Handler> mHandlerRef;
public SomeRunnable(Handler handler) throws IOException {
. . .
mHandlerRef = new WeakReference<Handler>( handler );
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
. . .
Handler mHandler = mHandlerRef.get();
if( mHandler != null ) {
Message msg = mHandler.obtainMessage();
. . .
mHandler.sendMessage(msg);
}
}
} catch (IOException e) {
Log.e("Error", e.hashCode() + ": " + e.getLocalizedMessage());
}
}
}
}
Upvotes: 1