6

onLoadFinished我在回调(来自)上返回了一个游标LoaderManager.LoaderCallbacks,我想对这个游标进行一些(可能成本高昂的)后处理。所以,我正在启动一个AsyncTask使用此光标的程序。但是,我遇到了此异常的间歇性崩溃:

android.database.StaleDataException: Attempted to access a cursor after it has been closed.

我怀疑这是因为游标(由 UI 线程中的加载程序管理)在后台线程完成之前关闭,因为这是一个托管游标。这是一些转述的代码:

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();
}

有没有可能,

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

  2. 通知经理游标仍在使用中。

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

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

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

4

2 回答 2

3

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

不(好吧,不是没有重写内部 API)。

是否可以通知经理游标仍在使用中?

和上面的回答一样。

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

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

有更好的解决方案吗?

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

于 2012-06-09T00:10:33.043 回答
0

伙计,我面临着同样的问题。方法是在activity的onDestroy方法中取消asynctask。

private YourAsyncTask asyncTask

@Override
protected void onDestroy(){
    super.onDestroy();
    asyncTask.cancel(true);
}
于 2014-05-16T17:52:44.103 回答