使用游标从LoaderManager中的AsyncTask返回 [英] Using a Cursor returned from a LoaderManager in an AsyncTask

查看:314
本文介绍了使用游标从LoaderManager中的AsyncTask返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 onLoadFinished 回调返回游标(由 LoaderManager.LoaderCallbacks ),和我想要做的一些(可能是昂贵的)这个游标后处理。所以,我发射了一个的AsyncTask 使用此光标。不过,我得到间歇性崩溃与此异常:

  android.database.StaleDataException:试图访问一个游标已经关闭后。
 

我怀疑的是,这种情况正在发生,因为光标(由在UI线程加载器进行管理)被关闭前的后台线程完成它,因为这是一个托管光标。下面是一些转述code:

 私有类LoaderListener实现LoaderManager.LoaderCallbacks<光标> {
    @覆盖
    公共无效onCreateLoader(INT研发,捆绑参数){
        返回新CursorLoader(背景下,URI,投影,选择,selectionArgs两个,排序顺序);
    }

    @覆盖
    公共无效onLoadFinished(装载机<光标>装载机,光标光标){
        processCursor(光标)
    }
}

私人无效processCursor(最终光标光标){
    新的AsyncTask<虚空,虚空,结果> {
        @覆盖
        结果doInBackground(空... PARAMS){
            而(cursor.isAfterLast()== FALSE){
                //做光标一些昂贵的东西
            }
        }
    }。执行();
}
 

是否有可能要么,

  1. 不知何故标志光标移动到prevent它从UI线程被关闭。

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

  3. 克隆它,使克隆的实例不会获得由管理员关闭。

  4. 另外,更妙的是,解决方案呢?

有了这个后处理的UI线程上完成,绝对不是一个选项,但是,由于它可以是非常昂贵的。

解决方案
  

是否有可能以某种方式标志光标移动到prevent它从UI线程正在关闭?

没有(当然,不是没有重新编写的内部API)。

  

是否有可能通知经理光标仍在使用?

同样的答案同上。

  

是否可以克隆它,以使克隆的情况下没有得到由管理人员关闭?

这听起来有点凌乱...并且仍然有机会, LoaderManager 关闭游标,你能完成克隆它。

  

有没有更好的解决办法?

是的。查询,而不是试图重用,你传递给 LoaderManager 的一个新的光标。

I have a cursor returned on an onLoadFinished callback (from LoaderManager.LoaderCallbacks), and I want to do some (possibly costly) post-processing on this cursor. So, I'm firing off an AsyncTask that uses this Cursor. However, I'm getting intermittent crashes with this exception:

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

My suspicion is that this is happening because the cursor (being managed by the Loader in the UI Thread) is being closed before the background thread is finished with it, since this is a managed cursor. Here is some paraphrased code:

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

Is it possible to either,

  1. Somehow flag the cursor to prevent it from being closed from the UI thread.

  2. Notify the manager that the cursor is still in use.

  3. Clone it so that the cloned instance doesn't get closed by the manager.

  4. Another, even better, solution?

Having this post-processing done on the UI thread is absolutely not an option, however, as it can be very costly.

解决方案

Is it possible to somehow flag the cursor to prevent it from being closed from the UI thread?

No (well, not without re-writing the internal APIs).

Is it possible to notify the manager that the cursor is still in use?

Same answer as above.

Is it possible to clone it so that the cloned instance doesn't get closed by the manager?

This sounds kind of messy... and there is still the chance that the LoaderManager closes the cursor before you are able to finish cloning it.

Is there a better solution?

Yes. Query a new cursor instead of trying to reusing the one that you pass to the LoaderManager.

这篇关于使用游标从LoaderManager中的AsyncTask返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆