7

ビューで UI と参照を使用してフラグメントを保持すると、メモリ リークが発生する可能性があることを読みました。ビューにいくつかの参照を保存し、setRetaineInstance(true) を設定するフラグメントを使用してテスト アプリを作成するよりも、いくつかの画面回転によってリークが発生することはありません。MAT は、親アクティビティのインスタンスが 1 つしかないことを示しています。私が間違っていることは何ですか?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();
    }
}}

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;
}

}

4

1 に答える 1

7

ここでは、古いアクティビティの mLogin、mPassword、および ImageView ビューへの参照を保持していますが、onCreateView() が呼び出されるため、ローテーションの直後に上書きされるため、アクティビティがフロント アクティビティで構成の変更が発生した場合は問題ありません。

ただし、アクティビティがフロント アクティビティでない場合は、メモリ リークが発生する可能性があり、通常、フラグメントがどのように処理されるかを知ることはできません。

たとえば、ViewPager には 2 つの異なるアダプターがあり、1 つ ( http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html ) は Fragment インスタンスを保持しています (onDestroyView() を呼び出すだけです)。 other (FragmentStatePagerAdapter) がフラグメント インスタンスを破棄しています。

そのため、フラグメントを FragmentPagerAdapter から使用すると、大量のメモリ リークが発生します。

これが潜在的な問題の例として役立つことを願っています。何をしているのかわかっている場合は、 setRetaineInstance(true) を呼び出してビューを破棄しなくても問題ありません。

于 2013-09-08T20:49:30.083 に答える