2

我有一个使用加载器的片段。Fragment 实现了 LoaderManager.LoaderCallbacks。在onCreate()片段中,我做了一个setRetainInstance(true),以便片段不会在配置更改(如方向更改)时被破坏。这按预期工作,并且onDestroy()不调用片段的 。但是,当我旋转设备时,我的加载器被破坏了。每次我旋转设备时,都会创建一个新的加载器。我检查了内存转储并验证了这一点。

  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 回答