2010-09-10 8 views
6

Je suis actuellement confronté au problème suivant: chaque fois que mon application Android est démarrée, elle doit exécuter un certain code d'initialisation. Sans ce code, toutes mes activités/services au sein de l'application ne fonctionneront pas correctement. Jusqu'ici, j'ai mis ce code d'initialisation dans une activité SplashScreen, que j'ai déclarée comme activité PRINCIPALE dans le manifeste. Une fois le code d'initialisation exécuté, je termine() l'écran de démarrage et démarre l'activité principale actuelle, c'est-à-dire une activité composée de plusieurs onglets, à partir desquels l'utilisateur peut atteindre plusieurs autres activités.Initialisation d'une application Android

Le problème est maintenant le suivant: lorsque mon application est mise en arrière-plan, après un certain temps et après le lancement d'autres applications, mon application/processus est tué. Lorsque je le relance à partir de l'écran d'accueil, Android restaure la pile d'activité (tâche) et appelle onCreate() sur eux. Cependant, l'activité de l'écran de démarrage et donc le code d'initialisation ne sont pas exécutés, ce qui entraîne une exception.

Je pourrais mettre maintenant le code d'initialisation dans onCreate() de l'application, cependant ceci a comme conséquence un écran noir jusqu'à ce que la méthode finisse.

Est-ce que quelqu'un a une idée, où et comment je peux initialiser correctement mon application au démarrage?

Code d'initialisation:

public void init() { 
    if (initialized) { 
     return; 
    } 

    // Initialize terms 
    List<Tag> tags= DynamicDao.loadAll(Tag.class); 
    int numTags = tags.size(); 
    terms = new String[numTags]; 
    for (int i = 0; i < numTags; i++) { 
     terms[i] = tags.get(i).getTag(); 
    } 

    // Initialize document-term matrix 
    List<Item> items = DynamicDao.loadAll(Item.class); 
    createDocumentTermMatrix(items); 

    initialized = true; 
} 

Remarque: Un article a plusieurs étiquettes associées, dont j'ai besoin de créer un vecteur de document.

Répondre

2

Combien coûte votre initialisation? Qu'est-ce que tu fais là? En général, je recommande de ne pas utiliser un écran de démarrage (c'est une application mobile, pas une application de bureau). Au lieu de cela, utilisez un thread de travail pour initialiser vos données pendant l'affichage de l'interface utilisateur principale, puis utilisez handler pour initialiser l'interface utilisateur une fois que votre thread de travail est terminé.

Sinon, je voudrais voir pourquoi votre initialisation prend tellement de temps et l'optimiser. Que faites vous ici?

+0

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 nécessite environ 2-3 secondes sur un Nexus One, 6 secondes pour un HTC Magic et encore un peu plus long 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 les résultats de ce calcul dans un fichier au premier lancement de l'application et lire et juste mettre à jour à partir de là ... – Matthias

+0

Ecrire 3500 doubles ne devrait pas prendre 3 secondes. Quelque chose semble faux – Falmarri

+0

Je devrais peut-être donner quelques détails supplémentaires: cette matrice est une matrice de document Word, que je pré-compute en utilisant des entrées dans la base de données SQLite de l'application et que j'utilise pour calculer les similarités par la suite. – Matthias

1

Si vous devez vraiment exécuter une opération de longue durée, vous devez utiliser AsyncTask. Il est très simple à utiliser, il vous fournit deux fonctions appelées onPreExecute et onPostExecute qui sont invoquées dans le thread principal respectivement avant et après l'opération. Tous les trucs coûteux devraient aller dans doInBackground qui fonctionnera dans le thread de travail.

Pendant que vous faites cette opération, vous pouvez afficher une boîte de dialogue de progression (création à l'intérieur mentionnées ci-dessus OnPreExecute) montrant les progrès de ce que vous faites en utilisant l'un des callback fourni: onProgressUpdate vous serez alors fermer la boîte de dialogue dans l'intérieur mentionné ci-dessus onPostExecute

+0

Je ne sais pas pourquoi je ne peux pas commenter l'autre réponse va commenter ici: Si la matrice que vous allez calculer est utilisée par plus d'une activité au lieu de faire de cette classe un singleton, vous pourriez facilement sous-classer la classe Application (http://developer.android.com/reference/android/app/Application.html) (qui existera tant que l'une des activités ou services de votre application est en cours d'exécution) où vous pouvez stocker votre matrice qui sera être ensuite accessible depuis n'importe quelle partie de votre programme. – lucabox

+0

L'accès à la matrice à partir de plusieurs activités n'est pas le problème. Le problème est de savoir où calculer cette matrice. Dans une SplashScreenActivity, dans une classe de threads singleton ou dans Application.onCreate(). Application.onCreate() n'est pas une option, puisque l'utilisateur voit un écran noir jusqu'à ce que le calcul est en cours - je ne vois aucune possibilité de personnaliser cela, par exemple. en montrant une image personnalisée. Si j'utilise un SplashScreenActivity, j'ai le problème décrit dans la question. – Matthias

+0

En fait mon point (voir réponse principale) est d'utiliser ** AsyncTask ** pour ne pas bloquer le thread principal.Un thread séparé est nécessaire dans ** n'importe quel cas ** ou l'interface utilisateur sera bloquée et une asyncTask est un moyen simple et agréable d'exécuter quelque chose dans un thread différent et d'être averti lorsque l'opération est terminée. le rappel de mise à jour de progrès que j'ai mentionné). J'ai mentionné que la classe Application peut être utilisée * juste * pour stocker le résultat de l'opération de sorte qu'elle puisse être facilement accessible par toute activité/service présent dans l'application. – lucabox

0

Si vous souhaitez conserver votre écran de démarrage actuel, vous avez plusieurs options.

Si votre structure de données n'est pas trop colossale, vous pouvez la stocker dans onSaveInstanceState et la restaurer dans onRestoreInstanceState et/ou onPostCreate.Si les données sont trop volumineuses, il vous suffit de vérifier si votre application est initialisée dans onResume ou l'une des autres méthodes de démarrage telles que onRestart, onStart, etc. (je suis toujours un peu flou sur quand exactement chacun doit être utilisé.) Sinon, lancez votre écran d'accueil Activité.

Les conseils des autres sur ce sujet sont également bons. Mais cela peut fonctionner pour vous si vous avez besoin d'une solution rapide.