La documentation du SDK Android indique que cette startManagingCursor()
méthode est obsolète:
Cette méthode est obsolète. Utilisez plutôt la nouvelle classe CursorLoader avec LoaderManager; ceci est également disponible sur les anciennes plates-formes via le package de compatibilité Android. Cette méthode permet à l'activité de prendre en charge la gestion du cycle de vie du curseur donné pour vous en fonction du cycle de vie de l'activité. Autrement dit, lorsque l'activité est arrêtée, elle appellera automatiquement deactivate () sur le curseur donné, et quand elle sera redémarrée plus tard, elle appellera requery () pour vous. Lorsque l'activité est détruite, tous les curseurs gérés seront fermés automatiquement. Si vous ciblez HONEYCOMB ou une version ultérieure, envisagez plutôt d'utiliser LoaderManager, disponible via getLoaderManager ()
Je voudrais donc utiliser CursorLoader
. Mais comment puis-je l'utiliser avec personnalisé CursorAdapter
et sans ContentProvider
, quand j'ai besoin d'URI dans le constructeur de CursorLoader
?
la source
Réponses:
J'ai écrit un simple CursorLoader qui n'a pas besoin d'un fournisseur de contenu:
Il n'a besoin que de la
AsyncTaskLoader
classe. Soit celui d'Android 3.0 ou supérieur, soit celui fourni avec le package de compatibilité.J'ai également écrit un
ListLoader
qui est compatible avec leLoadManager
et est utilisé pour récupérer unejava.util.List
collection générique .la source
Écrivez votre propre chargeur qui utilise votre classe de base de données au lieu d'un fournisseur de contenu. Le moyen le plus simple consiste simplement à extraire la source de la
CursorLoader
classe de la bibliothèque de compatibilité et à remplacer les requêtes de fournisseur par des requêtes dans votre propre classe d'assistance db.la source
CursorLoader
descendant pour gérer un curseur SQLite, à part le constructeur, je n'avais besoin que de remplacer laloadInBackground
méthode pour remplacer la requête du fournisseur par ma requête de curseurLe SimpleCursorLoader est une solution simple, mais il ne prend pas en charge la mise à jour du chargeur lorsque les données changent. CommonsWare a une bibliothèque loaderex qui ajoute un SQLiteCursorLoader et prend en charge la nouvelle requête sur les modifications de données.
https://github.com/commonsguy/cwac-loaderex
la source
Une troisième option consisterait simplement à remplacer
loadInBackground
:Cela prendra également soin de ré-interroger votre curseur lorsque la base de données change.
Seule mise en garde: vous devrez définir un autre observateur, car Google, dans sa sagesse infinie, a décidé de rendre son package privé. Si vous mettez la classe dans le même package que l'original (ou le compat), vous pouvez en fait utiliser l'observateur d'origine. L'observateur est un objet très léger et n'est utilisé nulle part ailleurs, donc cela ne fait pas beaucoup de différence.
la source
loadInBackground()
, avant de renvoyer le curseur, dites quecursor.setNotificationUri(getContext().getContentResolver(), uri);
l'URI peut simplement provenir d'une chaîne aléatoire commeUri.parse("content://query_slot1")
. On dirait que ça ne se soucie pas que l'URI existe vraiment ou non. Et une fois que j'ai fait l'opération sur DB. DiregetContentResolver().notifyChange(uri, null);
ferait l'affaire. Ensuite, je peux créer quelques "emplacement d'uri de requête" dans un fichier contant pour l'application avec un petit nombre de requêtes. J'ai testé l'insertion de l'enregistrement DB dans le runtime et cela semble fonctionner mais je doute toujours que ce soit une bonne pratique dessus. Toute suggestion?La troisième option proposée par Timo Ohr, associée aux commentaires de Yeung, apporte la réponse la plus simple (le rasoir d'Occam). Voici un exemple de cours complet qui fonctionne pour moi. Il existe deux règles pour utiliser cette classe.
Chaque fois que la base de données sous-jacente change (par exemple, après une insertion ou une suppression), assurez-vous d'appeler
où myUri est le même que celui renvoyé par votre implémentation de la méthode getContentUri ().
Voici le code de la classe que j'ai utilisée:
la source