So from reading/research about memory leaks it suggests to make all inner classes static to avoid memory leaks. However, by looking at the SDK samples (specifically TicTacToeLib) they implement their callbacks without the use of static inner classes. Will this cause a memory leak? If not, why?
private Handler mHandler = new Handler(new MyHandlerCallback());
private class MyHandlerCallback implements Callback {
public boolean handleMessage(Message msg) {
if (msg.what == MSG_COMPUTER_TURN) {
// Pick a non-used cell at random. That's about all the AI you need for this game.
State[] data = mGameView.getData();
int used = 0;
while (used != 0x1F) {
int index = mRnd.nextInt(9);
if (((used >> index) & 1) == 0) {
used |= 1 << index;
if (data[index] == State.EMPTY) {
mGameView.setCell(index, mGameView.getCurrentPlayer());
break;
}
}
}
finishTurn();
return true;
}
return false;
}
}
Yes, this sample will cause a leak in case it keeps a
Messagein the queue. But it’s not a very severe leak since it is usually limited to a rather short amount of time.But there is a rather simple way to prevent the leak:
Put the following two classes into your project
And now you can use
Handler/Callbackalmost as you used to do but it’s no longer leaking.So either like
or like
The leak problem with
Handleris that eachMessage/Runnable(which is actually wrapped in aMessage) knows it’s target, i.e. has a hard reference to theHandlerorCallback. And if that target is a non-static inner class, it will have an implicit hard reference to the outer class which is typically anActivity.That means that as long as there are
Messagesenqueued for yourHandler, your wholeActivitycan’t be garbage collected.To solve this issue that chain of hard references from
MessagetoActivityhas to be broken. TheSafeCallbackclass does exactly that by keeping just aWeakReferencetowards yourActivity.That means, the
Messagehas now a hard reference toSafeCallbackbut the part bind there can now be garbage collected. In case that happensHandler.Callback callback = mCallback.get();will turn outnulland theMessageis simply discarded. There is no more useful target anyways. It is still leaking theSafeCallbackitself but that’s a pretty much empty class so it won’t lead to problems.