33 votes

Meilleure pratique pour gérer le changement d'orientation: Android

J'allais à travers diverses pratiques pour gérer changement d'orientation avec les fils et AsyncTask. Je suis tombé sur des solutions suivantes:

  1. Fixez-détacher modèle : attachement et le détachement de l'activité de threads et AsyncTask tout en préservant leur exemple. (Source: 1, 2)

  2. Headless fragment de façon : à l'Aide d'un non-UI/headless fragment de faire tout le fil des opérations et de la retenue de son instance sur les changements de configuration. (Source: 1, 2)

Existe-il d'autres approches pour gérer ce scénario? Quelle est la pratique recommandée? Je vous pose cette question parce que je ne pouvais pas trouver une solution générique de n'importe où dans google docs.

43voto

pjco Points 2503

Certains résumés

Il existe plusieurs méthodes mentionnées ci-dessus qui sont de bonnes pratiques, mais j'ai pensé que je pourrais les résumer, avec de courtes explications. Ci-dessous sont quelques-uns des plus populaires des bibliothèques utilisées actuellement pour http réseautage, de travail asynchrone / threading, et la mise en cache.

Mon projet actuel (juste préférences)

Personnellement, je suis actuellement en utilisant Otto, Chargeurs, Volley, Ormlite, et une pile de réseau basé sur Apache et Services. J'espère pour remplacer la pile réseau à un certain point avec soit de Volley, de Rénovation, et peut-être finalement Robospice.

J'ai personnellement beaucoup comme Otto et le Volley


RoboSpice (Modulaire)

  • https://github.com/octo-online/robospice
  • http://www.youtube.com/watch?v=ONaD1mB8r-A
  • un plugin / approche modulaire-long-tâches en cours d'exécution
  • c'est comme le "swiss army knife" des bibliothèques, mais vous avez besoin de savoir ce que chaque outil.
  • Gère les appels RESTE
  • persiste données par l'orientation et d'autres changements
  • peut gérer disque et de la mémoire cache )
  • travaille avec différentes HTTP bibliothèques et de la persistance des bibliothèques (Gson, Jackson, Printemps, OkHttp, et beaucoup de bibliothèques)
  • la bêta de Ormlite soutien, je pense que

Des protections (REPOS)

Volley (mise en Réseau des données et des Images)

Picasso (images)

Chargeurs (Android)

  • bien pris en charge
  • persister à travers l'orientation de modifier et de sauvegarder/charger des fragment de l'état
  • peut être difficile d'obtenir le droit
  • pas de mise en cache

AsyncTask (Android)

  • moyen simple pour le travail de fond du thread d'INTERFACE utilisateur
  • doit être annulé et soyez prudent sur les tâches que de retour après une activité ou d'un fragment est déchirée vers le bas.

Otto (event bus)

  • https://github.com/square/otto
  • Événement de bus qui permet une synchronisation de travail entre les composants et les fragments facile
  • Très puissant @Produce capacité conserve le dernier événement et peut le produire sur demande pour les nouveaux intéressés abonnés au bus

Headless Fragments (?)

  • Personnellement, je n'ai jamais vu cela utilisé d'autres que Vogella des tutoriels, donc je ne suis pas sûr que, sur ce point.

Service (Android)

  • Old school
  • contrôle ultime, vous devez tout faire vous-même
  • généralement utilisé avec Appache ou balancer des clients et
  • passer des Parcelles autour de la via Intentions

7voto

a.ch. Points 4560

Pourquoi n'essayez-vous pas Loaders, en particulier AsyncTaskLoader? Elles sont disponibles en pré-Nid d'abeille à travers Bibliothèque de prise en charge et parfaitement correspondre à l'Activité/Fragment du cycle de vie. Voici le résumé officiel:

  • Ils sont disponibles pour chaque Activité et le Fragment.
  • Ils fournissent le chargement asynchrone des données.
  • Ils veillent à la source de leurs données et de fournir de nouveaux résultats lorsque les changements de contenu.
  • Ils se reconnecter automatiquement à la dernière chargeur du curseur lors de l'être recréée après un changement de configuration. Ainsi, ils n'ont pas besoin de ré-interroger leurs données.

4voto

noni Points 1438

Nous sommes effectivement en utilisant RoboSpice de la bibliothèque. Il fonctionne sur un Service avec seulement la fourniture de RequestListeners objets.

Le problème avec votre première approche (en Gardant les références entre les AsyncTask), c'est que vous pouvez probablement générer des fuites de mémoire, parce que quand votre AsyncTasks détient vos Activités de références, ils seront ne sont pas des déchets collectés. Gardez un œil sur ce juste de profilage de votre demande de vérification de la Taille du Segment de mémoire de la rotation de la même Activité, encore et encore. Votre tas devrait croître dans les paramètres normaux (Il y a un moment où vos objets doivent être des ordures collectées vies en même temps avec de nouveaux objets), mais lorsque GC fonctionne votre allocation de RAM devrait tomber à la même taille que vous avez alloué au début.

Donc, si j'ai de recommander quelque chose va être la chose suivante:

L'activité de gestion des Appels de l'API et des Flux (Avec RoboSpice, de la location de l'INTERFACE utilisateur de faire pivoter) Des écrans simples à l'intérieur des Fragments à l'aide de retainInstance dans le vrai. Cela vous laisse passer votre Otd directement à vos fragments, et vous avez à gérer l'état au plus haut niveau de l'Activité.

3voto

AndroidHacker Points 1693

Si la manipulation asyncTask est votre préoccupation principale, j'.e pas prêt à télécharger des données à chaque fois que l'orientation est modifiée alors que vous pouvez essayer comme ceci:

(1) Initialiser une valeur quelconque avant sur créer comme ça ..

Boolean android_hacker = false;

(2) lorsque vous avez terminé avec le téléchargement de données sur la classe AsyncTask ensuite, réglez cette valeur à true

android_hacker = true;

Ici, maintenir toutes les données en utilisant le modèle et adaptateur Tableau de la classe

(3) Maintenant, chaque fois que l'orientation est modifiée de vérifier ensuite comme ceci

if( android_hacker = true ){

// Use your saved instance ..

}else{

// Download data as it is yet not downloaded ..

}

Espérons que cela aide ..

2voto

R4j Points 2884

Il existe de nombreuses façons que vous pouvez essayer à côté de l'AsyncTask. Et si vous essayez de trouver une meilleure pratique, AsyncTask n'est pas une bonne option. Cette réponse explique pourquoi vous ne devriez pas utiliser AsyncTask. Et ils vous recommandons d'utiliser une meilleure manière qui peut traiter avec de longs tâche en cours d'exécution, RoboSpice.
J'ai déjà utilisé cette bibliothèque et je pense qu'il est digne d'essayer: les activités de respect des cycles de vie (changement d'orientation), pas de fuites de mémoire, prend en charge le multi-threading, met en cache les résultats... On peut brancher et débrancher long de demande de tâche à l'aide de cache (mais il ne peut pas bien fonctionner, pour un non-cache à la demande).

Mais je vous conseille une bonne façon proviennent de Google: IntentService et BroadcastReceiver. Vous aurez enregistrées et non enregistrées de diffusion lors de changement d'orientation pour recevoir les données de résultat. Toute tâche d'arrière-plan de travail en IntentService et informer ce que vous voulez l'activité par BroadcastReceiver. Il y a beaucoup d'exemple que vous pouvez essayer. Quelque chose comme ceci: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/

Mise à jour:

Salut R4j, le point est que mon application est calme complexe. Et j'ai à faire nombre de réseaux parallèles d'appels. Votre approche avec IntentService est bon, mais n'est pas adapté pour des scénarios complexes

Je ne pense pas que ce soit un problème. Vous pouvez faire n'importe quoi avec la IntentService, même les tâches compliquées. Si vous voulez tâches en parallèle, vous pouvez considérer un Service avec le multithreading en elle et de communiquer avec l'activité par l'Intention. L'envoi d'intention entre le Service et l'activité est sûre et flexible, c'est-à Android manière.
Et si vous voulez cache (par fichier télécharger, diffuser, par base de données..) RoboSpice est un meilleur choix pour vous

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X