Memory leak when I replace a Fragment Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Memory leak when I replace a Fragment without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I have just started to use LeakCanary and when I replace a Fragment, every time leaks increase. This is the LeakCanary report:

android.widget.LinearLayout instance
​     Leaking: YES (ObjectWatcher was watching this because com.home.app1.PostFragment received Fragment#onDestroyView() callback 
     (references to its views should be cleared to prevent leaks))

This is my Fragment Replace code:

public void change(Fragment fragment) {

    ((FragmentActivity) context).getSupportFragmentManager().beginTransaction()

            .replace(R.id.frameLayout, fragment, "fragment")
            .setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
            .addToBackStack(null)
            .commit();
}

So I research on SO and some people say views must be clenead in onDestroyView. Then I tried this in onDestroyView: fragmentView=null; but nothing was changed. Also tried this:

if (view.getParent() != null) {
        ((ViewGroup) view.getParent()).removeView(view);
    }

But again nothing was changed. So I tried to make all views null like below:

   @Override
   public void onDestroyView() {
    super.onDestroyView();
    backButton=null;
    swipeLayout=null;
    imageView=null; ...etc.
   }

Eventually leaking warnings on LeakCanary disappeared. But I think this is not a solution and does not make sense because there may be many views. So what’s the solution to avoid this leaks? Thanks.

Answer

So I tried to make all views null like below

Eventually leaking warnings on LeakCanary disappeared.

You’ve found the solution – you were holding onto View references (your backButton, swipeLayout, imageView, etc.) after they were removed and supposed to be destroyed (onDestroyView). Since holding a reference to them prevents them from being garbage collected, that’s a memory leak.

But I think this is not a solution and does not make sense because there may be many views. So what’s the solution to avoid this leaks?

If you’re storing Views in member variables manually, that’s the best solution. You could use findViewById to find it every time, but I wouldn’t recommend it because you’ll incur a performance penalty from repeatedly traversing the View hierarchy.

You can avoid both of those problems by using the View Binding feature of the Android development tooling. With that, you’ll just have one Binding object to get rid of.

You could also use Butter Knife to manage your View variables for you – see the unbinder.unbind(); pattern mentioned on that page.

We are here to answer your question about Memory leak when I replace a Fragment - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji