2

ローダーを使用するフラグメントがあります。Fragment は LoaderManager.LoaderCallbacks を実装します。onCreate()フラグメントので、setRetainInstance(true)向きの変更などの構成変更でフラグメントが破壊されないようにします。これは期待どおりに機能onDestroy()し、フラグメントの for は呼び出されません。ただし、デバイスを回転させると、ローダーが破棄されます。デバイスを回転させるたびに、新しいローダーが作成されます。メモリダンプをチェックして、これを確認しました。

  1. なぜこうなった
  2. どうすればこれを回避できますか?

編集:混乱を避けるために:ローカル変数ローダーはここでは関係ありません。以前に作成したローダーが存在するかどうかを確認するだけです。以下の更新されたコード (ローカル変数を削除) でも、ローダーは破棄されます。

関連するコードを次に示します。

    public class MyFragment extends Fragment implements LoaderManager.LoaderCallbacks<Object> {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true); //Don't destroy fragment across orientation change
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated, myTid : " + android.os.Process.myTid());

        mLoaderManager = getLoaderManager();
        mLoaderManager.initLoader(MY_LOADER, null, this);
    }

    @Override
    public Loader<Object> onCreateLoader(int i, Bundle bundle) {
        Log.d(TAG, "onCreateLoader, myTid : " + android.os.Process.myTid());
        return new MyLoader(getActivity().getApplicationContext());
    }

   @Override
    public void onLoaderReset(Loader<Object> objectLoader) {
        Log.d(TAG, "onLoaderReset, myTid : " + android.os.Process.myTid());

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mTxtSomeTxt != null) {
                    mTxtSomeTxt.setText("");
                }
            }
        });
    }

    }
4

1 に答える 1

1

パーティーに少し遅れて...

保持されたフラグメントについては、initLoader(...) から返されたローダーを保存する必要があり、構成の変更が発生したときに元のローダーを返します。

private Loader<Object> myLoader;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    Log.d(TAG, "onActivityCreated, myTid : " + android.os.Process.myTid());

    mLoaderManager = getLoaderManager();
    myLoader = mLoaderManager.initLoader(MY_LOADER, null, this);
}

@Override
public Loader<Object> onCreateLoader(int i, Bundle bundle) {
    Log.d(TAG, "onCreateLoader, myTid : " + android.os.Process.myTid());

    // Handle loader creation on retrained fragments
    if (myLoader != null)  {
        return myLoader;
    }

    return new MyLoader(getActivity().getApplicationContext());
}
于 2014-07-07T19:06:01.647 に答える