SQLite
 sql >> Base de données >  >> RDS >> SQLite

IntentService gèle l'interface utilisateur de mon application

Êtes-vous absolument certain qu'il s'agit du IntentService c'est la cause principale du blocage de l'interface utilisateur ? Les services d'intention sont spécialement conçus pour s'exécuter dans les threads de travail afin de décharger le traitement du thread principal (UI), l'une des principales raisons à cela étant d'aider à empêcher L'interface utilisateur se fige.

Essayez peut-être de commencer vos efforts de débogage au niveau de l'interface utilisateur. En particulier, ce que fournit le ResultReceiver au IntentService quand vous le démarrez, et que faites-vous dans le onReceiveResult méthode de rappel dans cette instance de récepteur ?

En dehors de cela, pour l'activité dans laquelle vous rencontrez des gels, vérifiez le type d'opérations que vous effectuez. Charger de grandes quantités de données à partir d'une base de données sur le thread principal (c'est-à-dire sans utiliser de Loader ou quelque chose de similaire pour décharger le traitement sur un thread de travail) est une cause fréquente de blocage de l'interface utilisateur, du moins d'après mon expérience jusqu'à présent.

Mettre à jour

Je pense avoir compris quel est le problème. Il y a deux problèmes principaux, tous deux liés à la façon dont vous utilisez Volley. Lorsque vous ajoutez une demande à la file d'attente Volley, elle est exécutée de manière asynchrone. Cela signifie que la queue la méthode revient immédiatement. Dans votre code de service d'intention, cela signifie que le service continue immédiatement à dire au ResultReceiver qu'il a terminé le traitement, alors qu'en réalité tout ce qu'il a fait est de mettre la demande en file d'attente. Les cinq services d'intention le feront, ce qui signifie que MainActivity sera conclu très rapidement. Ceci est le premier numéro.

Le deuxième problème explique le gel que vous rencontrez. Bien que Volley exécute les requêtes sur les threads de travail, il renvoie les réponses analysées aux requêtes sur le thread principal - voir la documentation ici. Cela signifie que tout le traitement de réponse que vous effectuez dans le service d'intention (mise des données dans la base de données, etc.) se produit réellement sur le thread principal (UI). Ceci explique le gel.

Ce que vous voulez probablement faire ici, c'est passer à l'utilisation de RequestFuture de Volley Au lieu. Cela transforme essentiellement une demande asynchrone en une demande synchrone en vous permettant de bloquer jusqu'à ce que la demande se termine. Pour cela, créez un futur du type approprié (JSONObject dans votre cas) et définissez-le à la fois comme écouteur et comme écouteur d'erreur pour la requête. Ensuite, mettez la demande en file d'attente comme vous le faites maintenant, et immédiatement après appelez le get méthode sur l'avenir. Cette méthode bloquera jusqu'à ce que la réponse ait terminé le traitement. Vous pouvez le faire dans un service d'intention, car il s'exécute sur un thread de travail, pas sur le thread d'interface utilisateur.

Si la requête réussit, vous obtiendrez les données renvoyées et vous pourrez exécuter toute la logique qui se trouve actuellement dans votre Response.Listener la mise en oeuvre. Si une erreur se produit (c'est-à-dire que la requête échoue pour une raison quelconque), le futur de la requête lèvera une exception que vous pourrez gérer pour prendre les mesures appropriées.

L'utilisation de requêtes futures est une approche assez différente de l'utilisation des écouteurs et vous devrez peut-être modifier un peu votre code pour le faire fonctionner, mais cela devrait résoudre les problèmes que vous rencontrez.

J'espère que cela vous aidera, et mes sincères excuses pour ne pas avoir détecté le bug plus tôt.