我遇到了Loader的问题。
我有一个Activity,它显示从本地DB检索的记录列表。活动开始时,记录将通过LoaderManager.initLoader()方法自动加载。
还可以通过ActionBarSherlock中的刷新按钮手动刷新列表。但是,在完成另一个向DB添加记录的活动之后,不会调用onLoadFinished。
我正在使用SimpleCursorLoader,这里是活动的代码段:
@Override
public void onStart() {
...
getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public void onPause() {
...
getSupportLoaderManager().destroyLoader(0);
}
public void refreshRecords() {
getSupportLoaderManager().restartLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, final Bundle args) {
Loader<Cursor> l = new SimpleCursorLoader(this) {
@Override
public Cursor loadInBackground() {
return recordDAO.getCursor();
}
};
l.forceLoad();
return l;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
// updateUI
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
问题是,在完成其他活动后,会调用onLoaderCreate
,但不会调用onLoaderFinished
。
经过一些调试后,我发现SimpleCursorAdapter.deliverResults()
也被调用了,萌芽结束于.. if (isReset()) { ..
我错过了什么吗?如何强制重新加载数据?
提前谢谢
答案 0 :(得分:16)
由于对
的讨论,我终于找到了解决这个问题的方法https://groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI
public static <T> void initLoader(final int loaderId, final Bundle args, final LoaderCallbacks<T> callbacks,
final LoaderManager loaderManager) {
final Loader<T> loader = loaderManager.getLoader(loaderId);
if (loader != null && loader.isReset()) {
loaderManager.restartLoader(loaderId, args, callbacks);
} else {
loaderManager.initLoader(loaderId, args, callbacks);
}
}
此外,从支持库28开始,请确保不要在Fragment.onCreate()
内调用initLoader。正如更新的文档所述
您通常在活动的
onCreate()
方法或片段的onActivityCreated()
方法中初始化Loader。
答案 1 :(得分:4)
RaB解决方案对我不起作用
我的解决方案,在重新启动之前总是破坏Loader
Loader<Cursor> loader = mLoaderManager.getLoader(mKeyLoader);
if (loader != null)
{
mLoaderManager.destroyLoader(mKeyLoader);
}
mLoaderManager.restartLoader(mKeyLoader, args, this);
答案 2 :(得分:2)
除了RaB的回答之外,如果您使用的是自定义Loader
,请确保在覆盖super
时致电deliverResult()
:
@Override
public void deliverResult(D data) {
super.deliverResult(data); // <--onLoadFinished() will not be called if you don't call this
...
}
答案 3 :(得分:1)
fwiw,在调用第一个onLoadFinished之前,第二次尝试立即重新启动加载器时遇到了类似的问题,导致两者都没有被调用。
这对我有用:
if( loader == null )
loader = loaderMngr.initLoader(
0, null, myLoaderCallbacks
);
else if( loader.isAbandoned() )
return;
else
loaderMngr.restartLoader(
0, null, myLoaderCallbacks
);
答案 4 :(得分:1)
检查支持库。使用此导入android.support.v4.app。不要使用android.app.loadermanager。
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
初始化零件
LoaderManager mLoaderManager=getSupportLoaderManager();
LoaderManager.LoaderCallbacks<Cursor> mCursorLoaderCallbacks=new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle cursor) {
return new CursorLoader(getActivity(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, COLUMNS_OF_INTEREST, null, null,
MediaStore.Video.Media.DATE_ADDED + " DESC");
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
};
mLoaderManager.initLoader(URL_LOADER_EXTERNAL, null, mCursorLoaderCallbacks);