1455 Stimmen

Neustart der Aktivität bei Rotation Android

Wenn ich in meiner Android-Anwendung das Gerät drehe (die Tastatur herausziehe), dann wird mein Activity neu gestartet wird ( onCreate aufgerufen wird). Wahrscheinlich sollte es so sein, aber ich mache einen großen Teil der anfänglichen Einstellungen in der onCreate Methode, ich brauche also beides:

  1. Legen Sie alle anfänglichen Einstellungen in einer anderen Funktion ab, damit sie nicht bei der Rotation des Geräts verloren gehen oder
  2. Mach es so onCreate wird nicht mehr aufgerufen und das Layout wird lediglich angepasst oder
  3. Beschränken Sie die Anwendung auf das Hochformat, damit onCreate nicht aufgerufen wird.

4 Stimmen

Eine recht ausführliche Erklärung, wie man lang laufende asynchrone Tasks bei Änderungen der Aktivitätskonfiguration beibehält, finden Sie unter dieser Blogbeitrag auch!

3 Stimmen

Dies ist keine direkte Antwort, da andere bereits geantwortet haben, aber ich lade Sie ein, einen Blick zu werfen auf LogLifeCycle um zu verstehen, was in Ihren Android-Anwendungen in Bezug auf die Lebenszyklen passiert.

995voto

Reto Meier Punkte 95825

Verwendung der Anwendungsklasse

Je nachdem, was Sie in Ihrer Initialisierung tun, könnten Sie eine neue Klasse erstellen, die die Application und verschieben Ihren Initialisierungscode in eine überschriebene onCreate Methode innerhalb dieser Klasse.

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

El onCreate in der Anwendungsklasse wird nur aufgerufen, wenn die gesamte Anwendung erstellt wird, so dass der Neustart der Aktivität bei Änderungen der Ausrichtung oder der Sichtbarkeit der Tastatur diese Funktion nicht auslöst.

Es ist eine gute Praxis, die Instanz dieser Klasse als Singleton darzustellen und die Anwendungsvariablen, die Sie initialisieren, mit Gettern und Settern darzustellen.

HINWEIS: Sie müssen den Namen Ihrer neuen Anwendungsklasse im Manifest angeben, damit sie registriert und verwendet werden kann:

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

Reagieren auf Konfigurationsänderungen [UPDATE: Dies ist seit API 13 veraltet; siehe die empfohlene Alternative ]

Als weitere Alternative können Sie Ihre Anwendung auf Ereignisse warten lassen, die einen Neustart auslösen würden - wie z. B. Änderungen der Ausrichtung und der Sichtbarkeit der Tastatur - und diese innerhalb Ihrer Aktivität verarbeiten.

Beginnen Sie mit dem Hinzufügen der android:configChanges Knoten zum Manifestknoten Ihrer Aktivität

 <activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

oder für Android 3.2 (API-Level 13) und neuer :

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:label="@string/app_name">

Dann überschreiben Sie innerhalb der Aktivität die onConfigurationChanged Methode und rufen setContentView um zu erzwingen, dass das GUI-Layout in der neuen Ausrichtung neu erstellt wird.

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

19 Stimmen

Ich glaube nicht, dass der zweite Ansatz funktioniert. Ich habe es versucht; eine Aktivität mit einem EditText. Ich schrieb etwas Text dort, ändern Sie die Ausrichtung und der Text war weg/zurückgesetzt.

237 Stimmen

Wir hoffen, dass es in Zukunft eine onRotate()-Methode geben wird. Sich um solche Dinge überhaupt kümmern zu müssen, ist ehrlich gesagt frustrierend.

3 Stimmen

Vergessen Sie nicht die keyboardHidden en android:configChanges . Das habe ich getan, und dadurch wurde die Aktivität zerstört und trotzdem neu erstellt.

191voto

Gorm Punkte 2679

Update für Android 3.2 und höher:

Vorsicht : Beginnend mit Android 3.2 (API-Level 13), die "Bildschirmgröße" ändert sich ebenfalls wenn das Gerät zwischen Hoch- und Querformat wechselt. Wenn Sie also bei der Entwicklung für API-Level 13 oder höher (wie durch die Attribute minSdkVersion und targetSdkVersion angegeben) Laufzeit-Neustarts aufgrund von Ausrichtungsänderungen verhindern möchten, müssen Sie das "screenSize" Wert zusätzlich zum "orientation" Wert. Das heißt, Sie müssen Folgendes deklarieren android:configChanges="orientation|screenSize" . Wenn Ihre Anwendung jedoch auf die API-Stufe 12 oder niedriger abzielt, verarbeitet Ihre Aktivität diese Konfigurationsänderung immer selbst (durch diese Konfigurationsänderung wird Ihre Aktivität nicht neu gestartet, selbst wenn sie auf einem Gerät mit Android 3.2 oder höher läuft).

1 Stimmen

Vielen Dank für diese Klarstellung, denn ein Kommentar weiter oben hätte mich fast dazu veranlasst, mich damit zu befassen. Ich bin derzeit Targeting API 8 und mein Code hat nicht screenSize auf configChanges und kann bestätigen, dass es funktioniert gut (ohne Neuausrichtung) auf dem Gerät, das ich habe, die ICS ausgeführt wird.

0 Stimmen

Danke für den Hinweis, ich hatte nur Android:configChanges="orientation|screenSize" eingestellt, und das Umschalten der Ausrichtung hat meine Aktivität neu erstellt, und ich konnte beim besten Willen nicht herausfinden, warum!

5 Stimmen

Hinzufügen von Android:configChanges sollte nur als letztes Mittel eingesetzt werden . Erwägen Sie die Verwendung Fragments y setRetainInstance stattdessen.

137voto

nebulae Punkte 2645

Anstatt zu versuchen, die onCreate() vor dem Abfeuern zu schützen, sollten Sie vielleicht versuchen, die Bundle savedInstanceState die an das Ereignis übergeben wird, um zu sehen, ob sie null ist oder nicht.

Wenn ich zum Beispiel eine Logik habe, die ausgeführt werden soll, wenn die Activity wirklich erstellt wird, nicht bei jeder Ausrichtungsänderung, ich führe diese Logik nur in der onCreate() nur, wenn die savedInstanceState null ist.

Andernfalls möchte ich immer noch, dass das Layout entsprechend der Ausrichtung neu gezeichnet wird.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

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

Ich weiß nicht, ob das die ultimative Antwort ist, aber für mich funktioniert es.

6 Stimmen

Und wo sparen Sie eigentlich Staat?

6 Stimmen

Dies scheint für mich zu funktionieren und es scheint bei weitem die einfachste Methode. ich bemerke, dass Sie nur 4 ups für diese (5 einschließlich meiner) vs. 373 für die Idee über subclassing Application, die mir scheint weit komplizierter. gibt es irgendeinen Nachteil diese Methode?

4 Stimmen

Diese Lösung hat bei mir hervorragend funktioniert. Ich konnte Intent serverintent = new Intent(MainActivity.this, MessageListener.class); y startService(serverintent); zur Erstellung einer serverSocket = new ServerSocket(0xcff2); y Socket client = serverSocket.accept(); mit einer BufferedReader(new InputStreamReader(client.getInputStream())); und konnte mein Android-Gerät drehen und die Client/Server-Verbindung aktiv halten, aber die GUI drehen lassen. Dem Handbuch zufolge wird savedInstanceState initialisiert, wenn die letzte Aktivität beendet wird.

104voto

Someone Somewhere Punkte 22958

Was ich getan habe...

im Manifest, im Abschnitt Aktivität, hinzugefügt:

android:configChanges="keyboardHidden|orientation"

im Code für die Aktivität implementiert:

//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();
}

3 Stimmen

Um zu verdeutlichen: mit meiner Implementierung können Sie jetzt Variable Initialisierung in onCreate() und onConfigurationChanged() wird einfach für die Bildschirmdrehung aufgerufen werden. Ihre Variablen sind jetzt von Bildschirmrotationen isoliert ;-) schön und ez

2 Stimmen

Ich habe alles getan, wie hier beschrieben, aber ich bekomme NullPointerException, wenn ich versuche, eine Schaltfläche nach der Ausrichtungsänderung zu drücken. Was könnte falsch sein?

5 Stimmen

Bedenken Sie, dass meine Antwort etwa 3 Jahre alt ist und Android sich ständig weiterentwickelt... Simon - haben Sie einen Link zu Beispielcode? Das ist, was die Leute brauchen.

71voto

GregD Punkte 6724

Was Sie beschreiben, ist das Standardverhalten. Sie müssen diese Ereignisse selbst erkennen und behandeln, indem Sie sie hinzufügen:

android:configChanges

zu Ihrem Manifest und dann die Änderungen, die Sie vornehmen möchten. Zur Orientierung würden Sie also verwenden:

android:configChanges="orientation"

und für die geöffnete oder geschlossene Tastatur würden Sie verwenden:

android:configChanges="keyboardHidden"

Wenn Sie beides behandeln wollen, können Sie sie einfach mit dem Befehl pipe trennen:

android:configChanges="keyboardHidden|orientation"

Dadurch wird die Methode onConfigurationChanged in der von Ihnen aufgerufenen Aktivität ausgelöst. Wenn Sie die Methode außer Kraft setzen, können Sie die neuen Werte übergeben.

Ich hoffe, das hilft.

3 Stimmen

@GregD Ich weiß, und deshalb ist jetzt ein guter Zeitpunkt, um ihn zu aktualisieren, damit er der heutigen Situation entspricht. In Anbetracht der Anzahl der "Upvotes", die diese Frage hat, wird immer noch von anderen Fragen auf SO auf sie verwiesen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X