Utilisation d'un curseur renvoyé d'un LoaderManager dans un AsyncTask

J'ai un curseur renvoyé sur un rappel onLoadFinished (à partir de LoaderManager.LoaderCallbacks ), et je souhaite effectuer un post-traitement (éventuellement coûteux) sur ce curseur. Alors, je lance un AsyncTask qui utilise ce Cursor. Cependant, j'ai des accidents intermittents avec cette exception:

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

Je soupçonne que cela se produit parce que le curseur (géré par Loader dans le thread UI) est fermé avant que le thread d'arrière-plan ne soit fini, car il s'agit d'un curseur géré. Voici un code paraphrasé:

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

Est-il possible, non plus,

  1. D'une certaine manière, marquez le curseur pour éviter qu'il ne soit fermé du thread UI.

  2. Avisez le gestionnaire que le curseur est encore utilisé.

  3. Cloner pour que l'instance clonée ne soit pas fermée par le gestionnaire.

  4. Une autre solution encore meilleure?

Le fait que ce post-traitement effectué sur le thread UI ne soit absolument pas une option, car cela peut être très coûteux.

  • SwapCursor erreur indéfinie
  • Impossible de lire la ligne 1, col -1 de CursorWindow. Assurez-vous que le curseur est initialisé correctement avant d'accéder à ses données
  • Idiom pour fermer un curseur
  • Android CursorLoader
  • Java.lang.IllegalStateException: Impossible de lire la ligne x col x à partir de CursorWindow. Assurez-vous que le curseur est initialisé correctement. Contacts
  • POJO's versus Cursors dans Android
  • Créez un curseur à partir d'un tableau codé en dur au lieu de DB
  • Existe-t-il un moyen plus rapide d'itérer à travers les lignes de la requête Sqlite?
  • 2 Solutions collect form web for “Utilisation d'un curseur renvoyé d'un LoaderManager dans un AsyncTask”

    Est-il possible de marquer le curseur pour empêcher qu'il soit fermé du thread UI?

    Non (eh bien, non sans réécrire les API internes).

    Est-il possible d'avertir le gestionnaire que le curseur est encore utilisé?

    Même réponse que ci-dessus.

    Est-il possible de le cloner afin que l'instance clonée ne soit pas fermée par le gestionnaire?

    Cela semble gênant … et il est toujours possible que LoaderManager ferme le curseur avant de finir de le cloner.

    Existe-t-il une meilleure solution?

    Oui. Demandez un nouveau curseur au lieu d'essayer de réutiliser celui que vous passez au LoaderManager .

    Homme, je suis confronté au même problème. La façon d'annuler l'asynctask dans la méthode OnDestroy de l'activité.

     private YourAsyncTask asyncTask @Override protected void onDestroy(){ super.onDestroy(); asyncTask.cancel(true); } 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.