支持库27.1.0 onLoaderFinished在启动片段时返回一个关闭的游标

时间:2018-03-27 23:45:24

标签: android android-support-library loader

更新到支持库27.1.0后,我的应用程序崩溃,似乎是由CursorLoader在onLoaderFinished()中返回一个关闭的游标引起的。

我在片段中使用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);
}

1 个答案:

答案 0 :(得分:0)

我在支持库28.0中有类似的问题。尽管在下一次出现片段时我关闭了片段onStop()中的游标,但我还是关闭了光标-这对我有帮助

override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) {
        if (loader.id == LOADER_ID ) {
            if (cursor?.isClosed == true)
                loaderManager.restartLoader(LOADER_ID, null, this)
            else
                adapter.swapCursor(cursor)
        }
    }

尽管这似乎是一种解决方法-我认为加载程序在某种程度上负责管理游标的生命周期并确保在关闭旧ID时确保新的游标。