7
votes

Initialisation d'une application Android

Je suis actuellement confronté au problème suivant: chaque fois que mon application Android est démarrée, elle doit exécuter un code d'initialisation fastidieux de temps. Sans ce code, toutes mes activités / services de l'application ne fonctionneront pas correctement.

Jusqu'à présent, j'ai mis ce code d'initialisation dans une activité de SplashScreen, que j'ai déclaré une activité principale dans le manifeste. Une fois que le code d'initialisation a été exécuté, j'ai terminé () l'écran de démarrage et démarrez l'activité principale réelle, c'est-à-dire une activité composée de plusieurs onglets, d'où l'utilisateur peut atteindre plusieurs autres activités.

Le problème est Maintenant, les éléments suivants: Lorsque mon application est mise en arrière-plan, après un certain temps et après avoir lancé d'autres applications, mon application / processus est tué. Lorsque je le relâche de l'écran d'accueil, Android restaure la pile d'activités (tâche) et invoque oncreate () sur eux. Cependant, l'activité de l'écran de Splash et donc le code d'initialisation n'est pas exécutée, ce qui entraîne une exception.

Je pourrais désormais mettre maintenant le code d'initialisation dans l'ONCRATEE () de l'application (). Jusqu'à ce que la méthode se termine.

Quelqu'un a-t-il une idée, où et comment je peux initialiser correctement mon application sur le démarrage?

code d'initialisation: xxx

Remarque: un élément comporte plusieurs balises associées, à partir de laquelle j'ai besoin de créer un vecteur de document.


0 commentaires

3 Réponses :


3
votes

À quel point votre initialisation est-elle chère? Qu'est-ce que tu fais là? En général, je vous recommanderais d'utiliser un écran éclabousseur (c'est une application mobile, pas une application de bureau). Au lieu de cela, utilisez un fil de travail pour initialiser vos données lorsque l'interface utilisateur principale est affichée, puis utilisez le gestionnaire pour initialiser l'interface utilisateur une fois que votre fil de travail est effectué.

Alternativement, je regarderais pourquoi votre initialisation prend si longtemps et l'optimise. Que faites-vous là-bas?


12 commentaires

Lors de l'initialisation, je crée une matrice de doubles de taille 50x70 afin d'accélérer certains calculs par la suite. Ce calcul a besoin d'environ 2-3 secondes sur un Nexus un, 6 secondes pour une magie HTC et toujours un peu plus longtemps sur l'émulateur. L'algorithme d'initialisation ne peut plus être optimisé. Finalement (mais je ne suis pas très convaincu de cette idée), je pourrais écrire des résultats de ce calcul dans un fichier au premier lancement de l'application et lire et juste mettre à jour à partir de là ...


Écrire 3500 Doubles ne doit pas prendre 3 secondes. Quelque chose semble faux


J'ai peut-être besoin de donner quelques détails de plus: cette matrice est une matrice de document Word-Document, que je préconise à l'aide d'entrées dans la DB SQLite DB de l'application et que j'utilise pour calculer les similitudes.


Cela semble toujours très inefficace. Vous regardez la base de données pour chacun de ces doubles? Tu veux publier du code? BTW, dans les deux cas, on dirait que ma suggestion d'utiliser un thread de travailleur serait parfaite ici. Assurez-vous de lui donner une priorité inférieure afin que l'interface utilisateur reste réactive.


Ok, j'ai maintenant posté une extrait de code. Comme vous pouvez le constater, j'ai lu une liste de balises et une liste d'éléments de la DB, que j'utilise ensuite pour construire une matrice à terme de document (composée de fréquences d'étiquettes pour chaque article) - donc je ne lis pas directement le double valeurs de la DB.


Avez-vous ajouté des minuteries? Voyez combien de temps chaque partie de ce bloc de code prend. Mesurez le temps qu'il faut pour faire Loadall, le temps de la boucle pour la boucle et le temps de Caredocumenttermmatrix.


Loadall () ne consomme que peu de temps; Environ 90% du calcul est nécessaire pour CreateDocumentterMmatrix () qui a une complexité O (n ^ 2). Cependant, CreateCumentterMmatrix () ne peut plus être amélioré.


Eh bien, alors il y a peu de point dans la publication du code qui ne prend pas beaucoup de temps :) Dans tous les cas, voulez-vous que nous vous aidais à optimiser cette fonction ou à cette réponse?


En fait, j'ai posté cet extrait que de sorte que vous ayez une idée approximative de ce qui devrait être effectué sur le démarrage de l'application - l'optimisation de cette fonction ne fait pas partie de cette question :-) En ce qui concerne votre réponse, je ne suis pas convaincu à 100% de la frayer un travailleur Fil dans mon activité principale actuelle - depuis à partir d'un point de vue de conception, ce code d'initialisation est nécessaire pour toutes les activités et ne devrait donc pas être liée à une seule activité.


Votre fil de travail n'a pas à être attaché à une activité. Le thread est attaché à votre processus et cela persiste à travers les activités. Vous pouvez créer une classe distincte, le déranger du fil et le traiter comme un singleton. Chaque activité le crée (s'il n'existe pas déjà) et l'utilise pour lire la matrice.


Ok, ça pourrait marcher! Merci pour cette suggestion. Je vais accepter cette réponse si je ne recevrai aucune meilleure proposition ...


Meilleure proposition? Tu parles de la trahison :)



2
votes

Si vous devez vraiment exécuter une opération de longue durée, vous devez utiliser ASYNCCTTK . C'est vraiment simple à utiliser, il vous fournit deux fonctions appelées onpexecute et surpostexecute qui sont invoquées dans le fil principal respectivement avant et après l'opération. Toutes les choses chères devraient aller dans doinbackground qui fonctionnera dans le fil du travailleur.

Pendant que vous faites cette opération, vous pouvez afficher une boîte de dialogue de progression (la créant à l'intérieur de ce qui précède OnpExecute ) montrant la progression de ce que vous faites en utilisant l'un des rappels fournis: ONPROGRESSUPDATEDATE Vous allez ensuite rejeter la boîte de dialogue dans l'intermédiaire mentionné ci-dessus à l'intérieur ONPOSTEXECUTE


3 commentaires

Je ne sais pas pourquoi je ne peux pas commenter sur l'autre réponse commenter ici: Si la matrice que vous allez calculer est utilisée par plus d'une activité au lieu de rendre cette classe A Singleton, vous pouvez facilement sous-classer l'application ( développeur.android.com/reference/android/app/Application.html ) classe (qui Il existe aussi longtemps que l'une des activités ou des services de votre application est en cours d'exécution) où vous pourriez stocker votre matrice qui sera ensuite accessible depuis n'importe quelle partie de votre programme.


L'accès à la matrice de plusieurs activités n'est pas le problème. Le problème est où calculer cette matrice. Dans une analyse splash, dans une classe de filetage singleton ou dans l'application.Oncreate (). Application.Oncreate () n'est pas une option, puisque l'utilisateur voit un écran noir jusqu'à ce que le calcul soit en cours - je ne vois aucune possibilité de personnaliser ceci, par exemple. en montrant une image personnalisée. Si j'utilise une splashscreenactivité, j'ai alors le problème comme décrit dans la question.


En fait, mon point (voir la réponse principale) est d'utiliser AsynccTask pour ne pas bloquer le fil principal. Un thread séparé est nécessaire dans N'importe quel cas ou l'interface utilisateur sera bloqué et un système d'asyncaptage est un moyen remarquable et facile d'exécuter quelque chose dans un fil différent et d'être averti lorsque l'opération est terminée et que l'opération se met à jour sur la progression. aussi (D'où le rappel de mise à jour de progrès que j'ai mentionné). J'ai mentionné que la classe d'application peut être utilisée juste pour stocker le résultat de l'opération afin de pouvoir être facilement accessible par n'importe quel activité / service présent dans l'application.



0
votes

Si vous souhaitez conserver votre écran Splash actuel, vous avez quelques options.

Si votre structure de données n'est pas trop colossale, vous pouvez la stocker dans OnsaveInstancestate et la restaurer à OnrestoreInstanCetate et / ou OnPostCreate.

Si les données sont trop grandes, vous devrez peut-être simplement vérifier si votre application est initialisée à Onresume ou à l'une des autres variétés de méthodes de démarrage tels que Onrestart, Onstart, etc. (Je suis toujours un peu brumeux sur quand exactement chacun devrait être utilisé.) Sinon, démarrez votre activité d'écran anti-éclaboussure.

Les conseils des autres sur ce sujet sont bons, aussi bien. Mais cela peut travailler pour vous si vous avez besoin d'une solution rapide.


0 commentaires