6

onLoadFinished(from )のコールバックでカーソルが返され、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

男、私はまったく同じ問題に直面しています。方法は、アクティビティの onDestroy メソッドで asynctask をキャンセルすることです。

private YourAsyncTask asyncTask

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