Getting “Called doStart when already started” from LoaderManager. Why?

a 夏天 提交于 2019-12-04 04:36:57

in your fragment move your initLoader method inside the onActivityCreated method.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);

    LoaderManager lm = getLoaderManager();
    lm.initLoader(LOADER_ID, null, this);
}

I've just finished a few hours long debugging session with the support library.

TL;DR: DO NOT CALL getLoaderManager in Fragment.onCreate, use onActivityCreated!
(this implies that you can't do initLoader before onActivityCreated)

Fragment.getLoaderManager() will lazily get a LoaderManager instance for you from the activity. However for this to be a valid one the fragment already has to be activated (FragmentManager.makeActive), which implies two things relevant here:

  • the Fragment has been added
    (FragmentManager.addFragment)
  • the Fragment has an internal identifier (mWho)
    (makeActive calls Fragment.setIndex)

The latter is really important because when you call Fragment.getLoaderManager() which in turn asks FragmentActivity.getLoaderManager(who, ...) for a real manager. When called from Fragment.onCreate() the makeActive call didn't happen yet so you'll get back a LoaderManagerImpl with mWho == null which is bad, because the framework will reassign the LoaderManager instance to every fragment which has similar lifecycle.

Because of this reassignment the LoaderManager has already been started by one fragment, but another one will try to start it as well, because the activity didn't know which fragment is asking, neither of them had their identity (mWho) yet.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!