【问题标题】:Using a Cursor returned from a LoaderManager in an AsyncTask在 AsyncTask 中使用从 LoaderManager 返回的游标
【发布时间】:2012-06-08 23:49:08
【问题描述】:

我在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 线程上完成此后处理绝对不是一种选择,因为它可能非常昂贵。

【问题讨论】:

  • 您总是可以跳过CursorLoader 并在AsyncTask 中进行初始查询+ 昂贵的处理。
  • 你在用这个光标做别的事吗?

标签: java android android-cursor android-loadermanager


【解决方案1】:

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

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

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

与上面的答案相同。

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

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

有没有更好的解决方案?

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

【讨论】:

  • 你能说得更具体点吗?根据我对您的回答的理解,我仍然需要对新光标进行后处理,导致同样的问题......?
  • 请问您要做什么?为什么您的“后处理”与LoaderManager 生命周期捆绑在一起?为什么不单独对待它们呢?这样会干净很多……
【解决方案2】:

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

private YourAsyncTask asyncTask

@Override
protected void onDestroy(){
    super.onDestroy();
    asyncTask.cancel(true);
}

【讨论】:

  • 我面临与 Tshepang 完全相同的问题。没有一个响应实际上提供了解决方案。 “查询另一个游标”的建议似乎有点荒谬。我想您可以从原始版本中构建一个 MatrixCursor,这是某种形式的克隆。取消 AsyncTask 也没有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多