为什么建议不要使用UI保留片段?

Bra*_*bra 7 android memory-leaks android-fragments

我读到用ui保留片段和视图引用会导致内存泄漏.比我用片段创建测试应用程序,我在视图上存储一些引用并设置setRetaineInstance(true),但是几个屏幕旋转不会导致任何泄漏.MAT说我只有一个父活动实例.我做错了什么?在哪些情况下用ui保留片段会导致泄漏?

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();
    }
}}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

}

Jac*_*alk 7

在这里,您将保留对旧活动的mLogin,mPassword和ImageView视图的引用,但它们会在轮换后被覆盖,因为onCreateView()将被调用,因此如果您的活动是前端活动并且发生配置更改,那么您应该没问题.

但是,如果您的活动不是前台活动,则可能会遇到内存泄漏,并且通常您无法知道您的片段是如何处理的.

例如,ViewPager有两个不同的适配器,一个(http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html)保留Fragment实例(只是调用onDestroyView()),而其他(FragmentStatePagerAdapter)正在销毁片段实例.

因此,如果从FragmentPagerAdapter使用,您的片段将泄漏大量内存.

我希望这可以作为潜在问题的一个例子.如果您知道自己在做什么,那么调用setRetaineInstance(true)并且不处理视图是没有问题的.

  • 它完全按照预期工作.FragmentPagerAdapter保留所有10个实例,FragmentStatePagerAdapter只保留可见实例和它的邻居.你问的是内存泄漏,在这里你得到它:在屏幕旋转后,FragmentPagerAdapter将在可见实例上调用onCreateView并且它是2个邻居,从而删除对你的按钮和imageview的旧引用.其余7个实例将保留其旧引用,直到用户滑动查看它们. (4认同)