Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it's recommended not to retain fragment with UI?

I read that retaining fragment with ui and references on views can cause memory leaks. Than I create test app with fragment where I store some references on views and set setRetaineInstance(true), but several screen rotation does not cause any leaks. MAT says that I have only one instance of parent activity. What I'm doing wrong? In which cases retaining fragment with ui can cause leaks?

RetainInstanceActivity.java

public class RetainInstanceActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {        
    super.onCreate(savedInstanceState);

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(android.R.id.content, RetainFragment.newInstance())
                .commit();
    }
}}

RetainFragment.java

public class RetainFragment extends Fragment {

private View mLogin;
private View mPassword;
private View ImageView;

public static RetainFragment newInstance() {
    final RetainFragment fragment = new RetainFragment();

    return fragment;
}

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);        
}

@Override
public View onCreateView(final LayoutInflater inflater,
        final ViewGroup container, final Bundle savedInstanceState) {       
    final View view = inflater.inflate(R.layout.fragment_retain, container,
            false);

    mLogin = view.findViewById(R.id.login);
    mPassword = view.findViewById(R.id.password);
    ImageView = view.findViewById(R.id.img);

    return view;
}

}

like image 769
Bracadabra Avatar asked Sep 07 '13 06:09

Bracadabra


1 Answers

Here you are retaining references to the old activity's mLogin, mPassword and ImageView views, but they are overwritten right after rotation, as onCreateView() will be called, so if your activity is the front activity and a configuration change happens you should be fine.

You might run into memory leaks when if your activity isnt the front activity, though, and in general you can't know how your fragment is handled.

For example the ViewPager has 2 different adapters, one (http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html) is retaining the Fragment instances (just calling onDestroyView()), while the other (FragmentStatePagerAdapter) is destroying the fragment instances.

So, your fragment would leak significant memory if used from a FragmentPagerAdapter.

I hope this serves as an example of potential problems. If you know what you are doing then there's no problem invoking setRetaineInstance(true) and not disposing the views.

like image 94
Jacob Nordfalk Avatar answered Sep 24 '22 10:09

Jacob Nordfalk