使用从AsyncTask中的LoaderManager返回的Cursor

Lui*_*ger 6 java android cursor android-loadermanager

我在onLoadFinished回调(from LoaderManager.LoaderCallbacks)上返回了一个游标,我想对这个游标进行一些(可能是昂贵的)后处理.所以,我正在开火AsyncTask使用这个Cursor.但是,我遇到了这种异常的间歇性崩溃:

android.database.StaleDataException: Attempted to access a cursor after it has been closed.
Run Code Online (Sandbox Code Playgroud)

我怀疑这种情况正在发生,因为游标(由UI线程中的Loader管理)在后台线程完成之前正在关闭,因为这是一个托管游标.这是一些释义代码:

private class LoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
    @Override
    public void onCreateLoader(int d, Bundle args) {
        return new CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        processCursor(cursor)    
    }
}

private void processCursor(final Cursor cursor) {
    new AsyncTask<Void, Void, Result> {
        @Override
        Result doInBackground(Void... params) {
            while(cursor.isAfterLast() == false) {
                // doing some costly things with cursor
            }
        }
    }.execute();
}
Run Code Online (Sandbox Code Playgroud)

是否有可能,

  1. 以某种方式标记光标以防止它从UI线程关闭.

  2. 通知管理器光标仍在使用中.

  3. 克隆它,以便管理器不会关闭克隆的实例.

  4. 另一个甚至更好的解决方案?

然而,在UI线程上完成此后处理绝对不是一种选择,因为它可能非常昂贵.

Ale*_*ood 3

是否可以以某种方式标记光标以防止它从 UI 线程关闭?

不(好吧,如果不重写内部 API 就不行)。

是否可以通知管理员光标仍在使用中?

与上面的答案相同。

是否可以克隆它,以便克隆的实例不会被管理器关闭?

这听起来有点混乱......并且仍然有可能LoaderManager在完成克隆之前关闭光标。

有更好的解决方案吗?

是的。查询一个新游标,而不是尝试重用传递给LoaderManager.