更改方向后,装载程序无法重新启动

我想用一个演示来显示这个:

enter code here @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.button1); button.setOnClickListener(buttonClickListener); } private OnClickListener buttonClickListener = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub startMyLoader(); } }; private void startMyLoader() { getLoaderManager().destroyLoader(0); getLoaderManager().restartLoader(0, null, myLoaderListener); } /** * The listener for the group metadata loader. */ private final LoaderManager.LoaderCallbacks<Cursor> myLoaderListener = new LoaderCallbacks<Cursor>() { @Override public CursorLoader onCreateLoader(int id, Bundle args) { return new CursorLoader(LoaderDemoActivity.this, ContactsContract.Contacts.CONTENT_URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { cursor.moveToPosition(-1); if (cursor.moveToNext()) { Context context = getApplicationContext(); CharSequence text = "Load finished!"; int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(context, text, duration); toast.show(); } } @Override public void onLoaderReset(Loader<Cursor> loader) { } }; enter code here 

方向改变后,我点击button,onCreateLoader可以被调用,但onLoadFinished不会被调用。

这似乎很奇怪。

提前感谢您的帮助。

Solutions Collecting From Web of "更改方向后,装载程序无法重新启动"

我面临同样的问题。 请尝试在onCreate中调用this.getSupportLoaderManager()。 它解决了我的问题。 希望它能帮助你

我想我find了原因。

在Activity onCreate中,它将从NonConfigurationInstances中加载所有LoaderMangers(自己的或它的子片段)。

  if (mLastNonConfigurationInstances != null) { mAllLoaderManagers = mLastNonConfigurationInstances.loaders; } 

在Activity onStart中,它将尝试启动它自己的LoaderManger。

  if (!mLoadersStarted) { mLoadersStarted = true; if (mLoaderManager != null) { mLoaderManager.doStart(); } else if (!mCheckedForLoaderManager) { mLoaderManager = getLoaderManager(-1, mLoadersStarted, false); } mCheckedForLoaderManager = true; } 

但是在configuration改变之后,mLoaderManager == null,所以它不会启动它。 这是问题! 如果你尝试启动加载器属于这个loaderManager,将会失败。

 void installLoader(LoaderInfo info) { mLoaders.put(info.mId, info); if (mStarted) { // The activity will start all existing loaders in it's onStart(), // so only start them here if we're past that point of the activitiy's // life cycle info.start(); } } 

注意当启动LoaderManager时mStarted的值将被设置为“true”。

有两种方法可以解决这个问题。

  1. 调用onCreate()中的getLoaderManger(),它将重新分配mLoaderManager,并使其准备好在onStart()子库中启动。

    public LoaderManager getLoaderManager(){if(mLoaderManager!= null){return mLoaderManager; } mCheckedForLoaderManager = true; mLoaderManager = getLoaderManager(-1,mLoadersStarted,true); 返回mLoaderManager; }

  2. 装载机位于碎片。 因为在Fragments的onStart()中,它将启动它自己的LoaderManager。

    如果(!mLoadersStarted){mLoadersStarted = true; if(!mCheckedForLoaderManager){mCheckedForLoaderManager = true; mLoaderManager = mActivity.getLoaderManager(mIndex,mLoadersStarted,false); if(mLoaderManager!= null){mLoaderManager.doStart(); }}

你不需要(既不应该)破坏你的Loader ,以重新加载它。 Loader类旨在可重用。

改用initLoader 。 例如。:

 getLoaderManager().initLoader(0, null, myLoaderListener); 

如果你想强制重新加载已经注册的加载器:

 getLoaderManager().getLoader(0).forceLoad(); 

如果您不确定configuration更改事件发生后Loader实例是否已经存在,请使用initLoader而不是getLoader来检索您可以调用forceLoad() Loader实例。

getLoaderManager().initLoader(0, null, myLoaderListener).forceLoad();

如果你使用的支持库,然后使用forceLoad即使第一次即时 – – 可能是一个错误 – 我提醒自己有一些关于它在这个论坛上的问题 – 尝试search旧post。

onCreate活动中调用加载器之前,请确保您没有在使用片段时检查savedStateInfo

 @Override public void onCreate(Bundle savedInstanceState) { // used to not overlap fragments if (savedInstanceState != null) { return null; } loadFragments(); getSupportLoaderManager().restartLoader(LISTS_LOADER, null, this); } 

如果您需要检查savedInstanceState碎片,您可以检查在加载器加载完成后应该创build的任何类variables,因为在旋转时活动会被破坏,而在旋转回来时将从之前的状态boost。

从android的开发网站

它们在configuration更改后重新创build时会自动重新连接到最后一个加载器的光标,因此不需要重新查询它们的数据。

据我了解,即使我们明确启动加载器,加载器不会启动。 由于我们所调用的销毁应该在销毁之后调用onLoaderReset() 。 但是一旦方向被改变,该方法就不会被调用,而是被调用。

我仍然可能是错的。 这是我的假设。 进一步的讨论将不胜感激。