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.

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); } 
  • Java.lang.ClassNotFoundException pour mon application
  • L'horodatage indique les mauvaises données
  • Android ExpandableListView ne s'élargit pas / ne peut pas être cliqué
  • Pourquoi IntentReceiverLeaked?
  • Qui a un matériel sur la façon de travailler avec l'API Face Detection Camera 2?
  • Android Studio 2.1: erreur: package org.junit n'existe pas
  • Le temps de Java, la batterie System.nanoTime () que System.currentTimeMillis (), mais persiste-t-il pendant le sommeil?
  • TextToSpeech setLanguage ne fonctionne pas?
  • coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.