With the standard implementation pattern for a inner class Handler in an activity, the following is common:
public class MainActivity extends Activity { private class CHandler extends Handler { public void handleMessage(Message msg) { //handle message } } } }
While valid most of the time, this produce the warning “The handler class should be static or leak might occur”. More information of the error can be found here (search on page for HandlerLeak)
The reason why this warning is showing up lies with how inner class works. The handler class will implicitly hold a copy of the activity, making it ineligible for gc and thus the resources of the whole activity cannot be freed even when all references to the activity disappears. See the quote below from Romain Guy:
a Message has a reference to the Handler which, when it’s inner and non-static, has a reference to the outer this (an Activity for instance.) If the Message lives in the queue for a long time, which happens fairly easily when posting a delayed message for instance, you keep a reference to the Activity and “leak” all the views and resources. It gets even worse when you obtain a Message and don’t post it right away but keep it somewhere (for instance in a static structure) for later use.
Solution
Simply making the Handler static does not help, because once it is static, to access the activity you still have to pass a reference to the static Handler class. This reference is a strong reference and thus the same problem is still there. The solution lies with WeakReference and/or static Handler. Below is an example setup I have (this works for updating the fragment):
private static class WeakRefHandler extends Handler { private WeakReference<Fragment> ref; public WeakRefHandler(Fragment ref) { this.ref = new WeakReference<Fragment>(ref); } @Override public void handleMessage(Message msg) { Fragment f = ref.get(); // handle message and update fragment } }; private WeakRefHandler mHandler = new WeakRefHandler(this);