Inside of the handler after I first enter the app from a clean state, the Handler handles the MSG_PULLED action however, the reference to main is null. The weak reference is not null. How can this possibly be happening?
Inspired by this post: This Handler class should be static or leaks might occur: IncomingHandler
static class MainHandler extends Handler {
private final WeakReference<MainActivity> wMain;
static int angle=0;
public MainHandler(MainActivity main) {
super();
this.wMain = new WeakReference<MainActivity>(main);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity main = wMain.get();
int what = msg.what;
if(what == MSG_PULLED) {
main.startAnim();
}
}
}
And how I initiate the handler:
static MainHandler mainHandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainHandler = new MainHandler(this);
mainHandler.sendEmptyMessageDelayed(MSG_PULLED,500);
}
The
Activityinstances in your app are regularly destroyed and new ones are created for example when rotating the display.Now what should happen in that case is that the old instance is garbage collected and only the new one exists. If you keep the old one around you have created a leak.
Since
Handlerare not garbage collectable until they have no more messages (?) they can live longer than theActivityin witch they were created, which usually leads to leaking the oldActivity(until theHandlercan be collected) sinceHandlerusually have a strong reference to theirActivity.The
WeakReferenceway in your code get’s rid of that problem by keeping just a weak link to theActivitythat does not prevent garbage collection.The problem is that you use the
get()method the wrong way:get()will only return the original object while it exists. When it’s gone you getnull. Here: theActivitywill exists while it is still the active one (determined by the system).The
nullis also not a big problem: when you getnullyourActivityinstance is no longer alive (maybe a new one was created, maybe it’s completely gone) so you can’t do anything useful with it anymore. Animation would not show even if you had still a reference.Basically do it like below and your problem is solved
The
WeakReferenceitself (wMain) is not null because it is itself strongly references as a member variable. Just the content inside it can / will benullat some point.