【发布时间】:2025-12-03 06:20:13
【问题描述】:
更新到支持库 27.1.0 后,我的应用程序崩溃了,这似乎是由于 CursorLoader 在 onLoaderFinished() 中返回关闭的游标所致。
我在 Fragment 中使用 Loader,我没有手动关闭光标。如果我回滚到支持库 27.0.2,一切正常。这是堆栈跟踪:
03-27 16:27:58.653 18706 18706 E AndroidRuntime: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: ...
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:151)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:123)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:237)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:259)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.database.CursorWrapper.moveToFirst(CursorWrapper.java:71)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at com.example.test.onLoadFinished(LeaderBoardFragment.java:104)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at com.example.test.onLoadFinished(LeaderBoardFragment.java:41)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.LoaderManagerImpl$LoaderObserver.onChanged(LoaderManagerImpl.java:221)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:121)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LiveData.access$400(LiveData.java:59)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:416)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:368)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:292)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:332)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:137)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.arch.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:123)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.Fragment.performStart(Fragment.java:2377)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1752)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1821)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2595)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2382)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2337)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2244)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:702)
03-27 16:27:58.653 18706 18706 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:790)
我在 onLoaderFinished() 中的代码如下:
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
super.onLoadFinished(loader, cursor);
int score;
if (loader.getId() == MY_LOADER_ID && cursor != null
&& getAbstractAdapter() != null) {
getAbstractAdapter().swapCursor(cursor);
if (cursor.getCount() > 0 && cursor.moveToFirst()) {
score = cursor.getInt(cursor
.getColumnIndex(0));
}
}
}
调用cursor.moveToFirst()时崩溃
来自onLoaderReset()的代码
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
【问题讨论】:
-
你能在你使用光标的地方添加代码吗?听起来您使用的是
changeCursor,而不是swapCursor。 -
@ianhanniballake 感谢您的浏览。请查看已编辑的问题,其中包含光标使用的代码。
-
@ianhanniballake 在对代码库进行更多挖掘之后,我发现加载程序只是开始使用
restartLoader()而不是首先调用initLoader()。深入研究 SupportLibrary 代码,看起来调用restartLoader将关闭“CursorLoader#onReset”中的游标。奇怪的是,LiveData 似乎保留了先前交付的光标(现已关闭)并在交付新光标之前将其返回给onLoaderFinished。 -
听起来像this issue,将在 27.1.1 中修复,即将发布。
-
@ianhanniballake 感谢您的信息。我会等待那个版本,看看它是否能解决我的问题。非常感谢您帮助社区。span>
标签: android android-support-library loader