9
votes

Fil principal fait trop de travail en raison d'appels de firebase asynchrones?

Je continue à obtenir une erreur sur mon application indiquant i / chorégraphe: sauté 252 cadres! La demande peut faire trop de travail sur son fil principal. Code> Je pense que cela provoque un retard sur mon interface utilisateur que je ne veux pas. Je pense que c'est parce que lorsque j'effectue une requête Firebase, lorsque je fais OndataChange () code>, il semble toujours être exécuté dans le fil d'interface utilisateur principal. J'ai environ 5 requêtes de Firebase similaires à ce que j'ai ci-dessous. En conséquence, j'ai essayé de déplacer mon code de Ondatacharge () code> méthode à un AsynccTask Code> et mettez à jour le thread d'interface utilisateur sur Onpostexecute () Code> Méthode de AsynccTask code>. Cependant, lorsque j'essaie ceci, la méthode onpostexecute () code> n'est jamais terminée. Voici ma tentative:

public void getPublicPosts(final View progressOverlay, final View fragmentView, final Context context) {
    //Need to do order by / equal to.
    Firebase postsRef = firebaseRef.child("Posts");
    Query query = postsRef.orderByChild("privacy").equalTo(PrivacyEnum.Public.toString());
    query.keepSynced(true);
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            asyncTaskWrapper(dataSnapshot, progressOverlay, fragmentView, context);
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {
            TabsUtil.populateNewsFeedList(fragmentView, application.getPublicAdapter(), TabEnum.Public, context);
        }
    });
}


4 commentaires

Au lieu de mettre en œuvre la mise en œuvre de l'asyncaptage à l'intérieur de la boucle, définissez-le séparément, puis l'exécuter à partir de la boucle, il fonctionnera donc sur un autre fil en toute sécurité.


@Vickyexpert Hi, je comprends ce que vous essayez de dire, mais je ne peux pas sembler trouver un moyen d'instancier asyncktask une fois sans le recréer plusieurs fois. J'ai posté ma tentative dans le post original.


Qu'est-ce que l'application.getpublicadapter () ?? Je pense que l'une des raisons pour le saut de la trame peut être cette application.getpublicAdapter (). GetPortsts (). Ajouter (0, Post) déclenche des notifications à plusieurs reprises. Cela pourrait également être la raison pour laquelle votre application se ferme comme notifyDatastetchanged ne peut pas être appelée dans le fil d'arrière-plan.


¿Il est nécessaire que vous montriez des progrès dans le fil principal?. Je pense que AsynccTask n'exécute que dans l'arrière-plan sur la fonction DOINBackground (). Ainsi, ce sera un système de fil et de gestionnaire plus efficace.


7 Réponses :


1
votes

Vous n'appelez pas exécutant () sur le système d'asyncaptage que vous avez créé, il ne sera donc jamais tiré.

Après vous avoir créé AsynccTask, appelez EXECUTE (URL ... paramètres) afin qu'il soit exécuté.

Aussi, je vois que vous n'utilisez pas les paramètres que vous passez, vous ne pouvez donc rien passer et cela fonctionnera.


1 commentaires

Hm, j'ai appelé exécuteur () après la création du asyncktask mais mon application sort désormais maintenant. Des idées pourquoi?



1
votes

Vous feriez mieux de faire des demandes de réseau sur Intitifservice. C'est facile et prévenir la congélation d'interface et / ou "l'application peut faire trop de travail sur son fil principal".

Regardez:

Intimentservice sur la documentation de développeur Android < / p>


0 commentaires

1
votes

Dans votre code, vous appelez l'ASYNTAST N TIME TIME BESTER BESTER que vous devez l'appeler une fois le pour: Chaque boucle utilisée doit être à l'intérieur du doInbackground () et à ONPROGRESSUPDate (), vous pouvez mettre à jour l'interface utilisateur au lieu de l'onpostexecute (), cette améliorera le code peu mais pas complètement, vous devriez utiliser une barre de progression sur ONPEXECUTE et rejetera la barre de progression à l'ouverture de l'onpostececute (), juste pour votre idée que j'ai l'écriture du code ci-dessous, mais je ne le réfère pas complètement comme je n'ai pas testé Ceci, mais forme cela va avoir une idée. XXX


1 commentaires

Hey j'ai essayé de suivre ce que vous avez suggéré, mais cela n'a pas bien fonctionné malheureusement. Toute autre idée?



3
votes

Votre thread principal est probablement lent car vous exécutez une boucle avec de nombreux objets. Cependant, ne sachant pas exactement ce que vous exécutez exactement, c'est juste une supposition.

Mais je pose problème avec votre asyncaptage, je ne pense pas que cela fonctionnera jamais avec le code que vous avez posté. P>

L'asyncaptage s'attend à une gamme d'URL. Vous n'en passez pas. Si vous n'avez pas besoin d'URLS comme entrée, utilisez simplement: P>

URL[] urls = new URL[2];
urls[0] = new URL(...);
urls[1] = new URL(...);
task.execute(urls);


0 commentaires

1
votes

Il aurait été beaucoup plus propre et plus facile à maintenir si vous avez créé une classe qui étend une classe d'asyncaptage et l'appelez-la comme celle-ci dans votre méthode OndataChange: xxx

de cette façon, vous exécutez votre façon de s'exécuter en toute sécurité. Firebase Connection Stuff dans un fil de travail et mettez à jour votre UI avec les résultats que vous avez récupérés.


0 commentaires

0
votes

Vous pouvez essayer quelques-unes des éléments suivants:

  • au lieu de créer et d'exécuter plusieurs n asynctacques, il suffit de créer et d'exécuter une seule avec la boucle Napshots à l'intérieur.
  • En Onpostexecute () Vérifiez que PopulaNewsfeedList La méthode ne fait pas de manipulations de données intensives, si vous pouvez également l'exécuter dans un nouveau asyncaptage et mettre à jour l'interface utilisateur après la fin.
  • Vous pouvez également essayer de mettre à jour les vues en passant une exécution en passant à la POST Méthode, cela en faisait enraciner les runnables dans la file d'attente du message du fil principal.
  • Vous pouvez exécuter vos longues opérations de course dans un service SERVICE ou A INTenteservice et mettez à jour votre UI via un ContentProvider ou émissions < / fort>.

    espère que cela aide.


0 commentaires

0
votes

Suggestions:

  1. Retirez le travail lourd du fil principal de l'UI, les excruit dans les autres threads.

    2.Quand les autres threads finissent le travail lourd, s'il doit mettre à jour l'interface utilisateur, utilisez le gestionnaire pour envoyer le fil principal de MSG à UI, puis mettez à jour l'interface utilisateur sur le fil principal.


0 commentaires