Handlers and memory leaks in Android Handlers and memory leaks in Android android android

Handlers and memory leaks in Android


I recently updated something similar in my own code. I just made the anonymous Handler class a protected inner class and the Lint warning went away. See if something like the below code will work for you:

public class MyGridFragment extends Fragment{    static class MyInnerHandler extends Handler{        WeakReference<MyGridFragment> mFrag;        MyInnerHandler(MyGridFragment aFragment) {            mFrag = new WeakReference<MyGridFragment>(aFragment);        }        @Override        public void handleMessage(Message message) {            MyGridFragment theFrag = mFrag.get();            switch (message.what) {            case 2:                ArrayList<HashMap<String,String>> theurls = (ArrayList<HashMap<String,String>>) message.obj;                theFrag.urls.addAll(theurls);                theFrag.theimageAdapter.notifyDataSetChanged();                theFrag.dismissBusyDialog();                break;            }//end switch        }    }    MyInnerHandler myHandler = new MyInnerHandler(this);}

You may have to change where I put "theFrag." as I could only guess as to what those referenced.


Here's a somewhat useful little class I made that you can use. Sadly it's still quite verbose because you can't have anonymous static inner classes.

import java.lang.ref.WeakReference;import android.os.Handler;import android.os.Message;/** A handler which keeps a weak reference to a fragment. According to * Android's lint, references to Handlers can be kept around for a long * time - longer than Fragments for example. So we should use handlers * that don't have strong references to the things they are handling for. *  * You can use this class to more or less forget about that requirement. * Unfortunately you can have anonymous static inner classes, so it is a * little more verbose. *  * Example use: *  *  private static class MsgHandler extends WeakReferenceHandler<MyFragment> *  { *      public MsgHandler(MyFragment fragment) { super(fragment); } *  *      @Override *      public void handleMessage(MyFragment fragment, Message msg) *      { *          fragment.doStuff(msg.arg1); *      } *  } *  *  // ... *  MsgHandler handler = new MsgHandler(this); */public abstract class WeakReferenceHandler<T> extends Handler{    private WeakReference<T> mReference;    public WeakReferenceHandler(T reference)    {        mReference = new WeakReference<T>(reference);    }    @Override    public void handleMessage(Message msg)    {        if (mReference.get() == null)            return;        handleMessage(mReference.get(), msg);    }    protected abstract void handleMessage(T reference, Message msg);}


Per the ADT 20 Changes, it looks like you should make it static.

New Lint Checks:

Check to make sure that Fragment classes are instantiatable. If you accidentally make a fragment innerclass non-static, or forget to have a default constructor, you can hit runtime errors when the system attempts to reinstantiate your fragment after a configuration change.

Look for handler leaks: This check makes sure that a handler inner class does not hold an implicit reference to its outer class.