10
votes

Android - SQLite ContentResolver Insertion / Supprimer / Mise à jour sur le thread d'interface utilisateur?

J'ai parcouru de nombreux exemples / tutoriels d'utilisation de SQLite dans Android. Disons que vous avez une application qui utilise sqlite, contentprovider , cursorloader , un Cursoradapter personnalisé . Maintenant, tous les principaux exemples de ce que j'ai trouvé comptez sur un cursorloader pour récupérer des données sur le cursoradapter , qui par la nature du cursorloader arrive dans une manière asynchronique de fil de sécurité. Cependant, ces mêmes exemples fabriquent tous des appels inserts / supprimés / de mise à jour via le "code> contentResolver sur le thread principal (par exemple à partir de onclick , tinrésume , Onparaause ). ( exemple ) Ils n'enveloppent pas ces appels dans un AsyncccTask ou lancez un thread séparé ou utilisez le AsyncQuyhandler . Pourquoi est-ce, comment tant de blogs / exemples peuvent-ils faire une telle erreur évidente? Ou sont des appels simples d'insert / Supprimer / Supprimer / Mettre à jour si rapidement qu'ils sont suffisamment sûrs pour se lancer dans le fil principal / UI? Quelle est la bonne façon de faire ces appels rapides?


1 commentaires

Votre dernière phrase est probablement bonne: le fonctionnement de la requête est certainement beaucoup plus complexe que Single Insertion / Mettre à jour / Supprimer


3 Réponses :


2
votes

Cette question a été dans mon esprit depuis longtemps. Je suppose que cela dépend de la complexité du fichier que nous essayons d'insérer, de mettre à jour ou de supprimer. Si notre application va insérer ou mettre à jour des fichiers volumineux, il serait toujours juste de le faire de manière asynchrone et si les fichiers ne seront pas si gros, le fonctionnement sur le thread de l'interface utilisateur peut être effectué.

Cependant, il est toujours recommandé de poursuivre les opérations de base de données sur un thread séparé.


1 commentaires

Merci pour la réponse. Cela n'explique pas vraiment pourquoi les tutoriels qui expliquent les meilleures pratiques et dans d'autres facettes font les choses correctement / en toute sécurité dans le cas de l'insert / Supprimer / la mise à jour ne se préoccupez jamais avec des threads séparés. Évidemment, je n'ai pas lu tous les bons tutoriels là-bas, alors de bons exemples de comptoirs seraient les bienvenus. (Surtout ceux de Google ou d'autres sources réputées)



0
votes

Je pense que vous avez répondu à votre propre question. Je crois que Cursorloader s'étend asynckttaskloader. Les appels fabriqués à partir d'un thread d'interface utilisateur ne traitent que l'appel au CUSORLOADER (qui utilise asynccaptask.) Qu'est-ce qui se fait par appel ne se produit toujours pas sur le fil de l'interface utilisateur. Passer un appel à une méthode / fonction qui exécute ensuite des choses sur un thread séparé fait encore du travail du fil de l'interface utilisateur.

Quel travail pensez-vous sur le fil de l'interface utilisateur?

Veuillez afficher le journal de débogage si possible ou par exemple où vous pensez que le travail est effectué sur l'interface utilisateur. Ça ne devrait pas être.

Ne pas essayer de discuter de savoir simplement savoir comment vous êtes arrivé à la conclusion du travail de l'interface utilisateur?


1 commentaires

Vous avez raison sur le chargeur de curseur étant asynchronisé. C'est ce que je me suis écrit dans la question. Toutefois, les appels Insérer / Supprimer / Mettre à jour sont effectués via le conteneurLover non cursorloader. Tout ce qui passe par le contenu du contenu est fait sur le fil de l'interface utilisateur, si l'appel est effectué sur le fil de l'interface utilisateur. Ceci est facile à vérifier simplement en ajoutant un thread.sleep (5000) au début de l'insertion de remplacement de votre fournisseur de contenu. Si vous le faites, vous verrez votre gel de l'interface utilisateur pendant 5 secondes ...



5
votes

Je suis également confus sur les échantillons effectuant des appels sur le fil principal. Je suppose que les échantillons ont simplement simplifié les démonstrations en évitant des threads et des rappels supplémentaires, puisque l'appel unique d'insertion / mise à jour / Supprimer peut retourner rapidement.

Outre le modèle de chargeur pour la requête, Android a fourni une classe d'assistance AsyncQuyhandler, puisque le niveau d'API 1, car ASYNC CRUD Opérations avec des rappels CRUD complets pris en charge. L'ASYNCQUERYHandler fonctionne à l'intérieur avec une poignée pour les opérations ASYNC et fournit les résultats du fil principal. P>

Donc, je crois que les requêtes de fournisseur de contenu devraient courir dans des threads de travailleur autres que l'interface utilisateur, et ces échantillons peuvent ne pas Soyez les meilleures pratiques selon la conception officielle. p>

=== Modifier P>

a trouvé une annotation du cadre officiel Docs, voir Ceci ou Ceci , ligne 255: P>

In practice, this should be done in an asynchronous thread instead of
on the main thread. For more discussion, see Loaders. If you are not
just reading data but modifying it, see {@link android.content.AsyncQueryHandler}.


4 commentaires

Droite, j'ai mentionné aussi l'asyncquérie de ma question aussi ... Il n'est toujours pas très convaincant que tous les tutoriels et exemples, que j'ai rencontré faire cela, juste parce que c'est plus simple et ne mentionne même pas que ce n'est pas Comment devriez-vous le faire. Pour une réponse appropriée, j'aimerais que quelque chose officiel de Google (membre de l'équipe, doc, tutoriel) ou quelque chose due à ces lignes (peut-être un lien vers un projet GitHub respectable qui fait cela une manière ou une autre) qui fait ces appels de lumière sur le Fil principal, ou utilise quelque chose comme AsyncQuyhandler ...


Sinon, tout le reste n'est que notre opinion sur ce ... :)


@Leok a obtenu un DOC officiel qui a mentionné cela. S'il vous plaît voir mes modifications.


Cool merci, indirect, mais confirme essentiellement ce que je voulais savoir. Merci. (P.S. J'ai ajouté un lien vers le document réel)