Question Redémarrage de l'activité sur la rotation Android


Dans mon application Android, lorsque je fais pivoter l'appareil (glisser le clavier) puis mon Activity est redémarré (onCreate est appelé). Maintenant, c'est probablement comme ça que ça doit être, mais je fais beaucoup de réglages initiaux onCreate méthode, donc j'ai besoin soit:

  1. Mettez toute la configuration initiale dans une autre fonction afin qu'elle ne soit pas perdue lors de la rotation de l'appareil ou
  2. Faire en sorte onCreate n'est pas appelé à nouveau et la disposition ajuste ou
  3. Limiter l'application à juste portrait afin que onCreate n'est pas appelé.

1222
2018-01-19 00:28


origine


Réponses:


Utilisation de la classe d'application

En fonction de ce que vous faites dans votre initialisation, vous pourriez envisager de créer une nouvelle classe qui étend Application et en déplaçant votre code d'initialisation dans un remplacement onCreate méthode dans cette classe.

public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}

le onCreate dans la classe d'application est seulement appelée quand l'application entière est créée, ainsi l'activité redémarre sur l'orientation ou les changements de visibilité du clavier ne la déclencheront pas.

Il est recommandé d'exposer l'instance de cette classe en tant que singleton et d'exposer les variables d'application que vous initialisez à l'aide de getters et de setters.

Remarque: vous devrez spécifier le nom de votre nouvelle classe Application dans le manifeste pour qu'il soit enregistré et utilisé:

<application
    android:name="com.you.yourapp.MyApplicationClass"

Réagir aux changements de configuration  [UPDATE: ceci est obsolète depuis API 13; voir l'alternative recommandée]

Comme alternative, vous pouvez demander à votre application d'écouter les événements qui provoqueraient un redémarrage - comme l'orientation et les changements de visibilité du clavier - et de les gérer dans votre activité.

Commencez par ajouter le android:configChanges noeud vers le noeud manifeste de votre activité

android:configChanges="keyboardHidden|orientation"

ou pour Android 3.2 (niveau d'API 13) et plus récent:

android:configChanges="keyboardHidden|orientation|screenSize"

Ensuite, dans l'activité, remplacez le onConfigurationChanged méthode et appel setContentView pour forcer la mise en page GUI à refaire dans la nouvelle orientation.

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}

896
2018-01-19 08:47



Mise à jour pour Android 3.2 et supérieur:

Mise en garde: Commençant avec Android 3.2 (niveau d'API 13), la "taille de l'écran" change également lorsque l'appareil bascule entre l'orientation portrait et paysage. Ainsi, si vous souhaitez empêcher les redémarrages d'exécution en raison d'un changement d'orientation lors du développement pour le niveau API 13 ou supérieur (comme indiqué par les attributs minSdkVersion et targetSdkVersion), vous devez inclure "screenSize" valeur en plus de la "orientation" valeur. Autrement dit, vous devez déclarer android:configChanges="orientation|screenSize". Toutefois, si votre application cible le niveau d'API 12 ou inférieur, votre activité gère toujours cette modification de configuration elle-même (cette modification de configuration ne redémarre pas votre activité, même si elle est exécutée sur un périphérique Android 3.2 ou supérieur).


175
2018-03-03 21:56



Au lieu d'essayer d'arrêter le onCreate() d'être renvoyé tout à fait, peut-être essayer de vérifier la Bundle  savedInstanceState étant passé dans l'événement pour voir si elle est nulle ou non.

Par exemple, si j'ai une logique qui devrait être exécuté lorsque le Activity est vraiment créé, pas sur chaque changement d'orientation, je ne fais que cette logique dans le onCreate()seulement si le savedInstanceState est nul.

Sinon, je souhaite toujours que la mise en page soit correctement redessinée pour l'orientation.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}

Je ne sais pas si c'est la réponse ultime, mais cela fonctionne pour moi.


110
2017-08-04 21:04



ce que j'ai fait...

dans le manifeste, à la section d'activité, ajouté:

android:configChanges="keyboardHidden|orientation"

dans le code de l'activité, implémenté:

//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
    //get views from ID's
    this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);

    //etc... hook up click listeners, whatever you need from the Views
}

//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    InitializeUI();
}

//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.main);

    InitializeUI();
}

93
2018-01-04 01:26



Ce que vous décrivez est le comportement par défaut. Vous devez détecter et gérer vous-même ces événements en ajoutant:

android:configChanges

à votre manifeste, puis les changements que vous voulez gérer. Donc, pour l'orientation, vous utiliseriez:

android:configChanges="orientation"

et pour le clavier étant ouvert ou fermé vous utiliseriez:

android:configChanges="keyboardHidden"

Si vous voulez gérer les deux, vous pouvez simplement les séparer avec la commande pipe comme:

android:configChanges="keyboardHidden|orientation"

Cela déclenchera la méthode onConfigurationChanged dans n'importe quelle activité que vous appelez. Si vous remplacez la méthode, vous pouvez transmettre les nouvelles valeurs.

J'espère que cela t'aides.


57
2018-01-19 02:28



Je viens de découvrir cette tradition:

Pour maintenir l'activité en vie grâce à un changement d'orientation, et le gérer à travers onConfigurationChanged, La documentation et l'exemple de code ci-dessus suggérer cela dans le fichier manifeste:

android:configChanges="keyboardHidden|orientation"

qui a l'avantage supplémentaire que cela fonctionne toujours.

La tradition de bonus est celle omettant le keyboardHidden peut sembler logique, mais cela provoque des échecs dans l'émulateur (pour Android 2.1 au moins): spécification uniquement orientation fera l'appel de l'émulateur à la fois OnCreate et onConfigurationChanged parfois, et seulement OnCreate d'autres fois.

Je n'ai pas vu l'échec sur un appareil, mais j'ai entendu parler de l'émulateur échouant pour les autres. Cela vaut donc la peine de documenter.


39
2017-12-22 21:50



Vous pouvez également envisager d'utiliser le mode de persistance des données de la plateforme Android pour les changements d'orientation: onRetainNonConfigurationInstance() et getLastNonConfigurationInstance().

Cela vous permet de conserver les données à travers les changements de configuration, tels que les informations que vous avez pu obtenir à partir d'une récupération de serveur ou d'autre chose qui a été calculée dans onCreate ou depuis, tout en permettant à Android de réorganiser votre Activity en utilisant le fichier xml pour l'orientation en cours d'utilisation.

Voir ici ou ici.

Il convient de noter que ces méthodes sont désormais obsolètes (bien que plus souples que la manipulation des changements d'orientation vous-même comme le suggèrent la plupart des solutions ci-dessus) avec la recommandation que tout le monde passe à Fragments et plutôt utiliser setRetainInstance(true) sur chaque Fragment vous voulez conserver.


33
2017-09-22 03:03



L'approche est utile mais incomplète lors de l'utilisation de Fragments.

Les fragments sont généralement recréés lors du changement de configuration. Si vous ne souhaitez pas que cela se produise, utilisez

setRetainInstance(true); dans le (s) constructeur (s) du Fragment

Cela entraînera la conservation des fragments pendant le changement de configuration.

http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)


28
2017-09-21 09:09



J'ai simplement ajouté

     android:configChanges="keyboard|keyboardHidden|orientation"

dans le fichier manifeste et n'a pas ajouté tout onConfigurationChanged méthode dans mon activité.

Donc à chaque fois que le clavier glisse ou que rien ne se passe.


21
2017-08-09 09:58



 onConfigurationChanged is called when the screen rotates. 
 (onCreate is no longer called when screen rotates due to manifest, see:  
 android:configChanges)

Quelle partie du manifeste dit "ne pas appeler onCreate()"?

Aussi, Les docs de Google disent d'éviter d'utiliser android:configChanges(sauf en dernier recours) .... Mais alors les méthodes alternatives qu'ils suggèrent tous FAIRE utilisation android:configChanges.

Il a été mon expérience que l'émulateur appelle TOUJOURS onCreate() lors de la rotation.
Mais les appareils 1-2 sur lesquels je cours le même code ... ne le font pas. (Je ne sais pas pourquoi il y aurait une différence.)


13
2018-02-01 15:55