Aktivität Neustart auf Rotation Android

1379

Wenn ich in meiner Android-Anwendung das Gerät Activitydrehe ( die Tastatur herausziehe), wird my neu gestartet ( onCreateheißt). Nun, das ist wahrscheinlich so, wie es sein soll, aber ich mache viele anfängliche Einstellungen in der onCreateMethode, also brauche ich entweder:

  1. Stellen Sie alle anfänglichen Einstellungen in eine andere Funktion, damit bei der Gerätedrehung oder nicht alles verloren geht
  2. Machen Sie es so onCreatewird nicht nochmal aufgerufen und das Layout passt sich einfach an oder
  3. Beschränken Sie die App auf nur Porträt, damit sie onCreatenicht aufgerufen wird.
Isaac Waller
quelle
4
In diesem Blog-Beitrag finden Sie auch eine ziemlich vollständige Erklärung, wie lang laufende asynchrone Aufgaben bei Änderungen der Aktivitätskonfiguration beibehalten werden können !
Adrian Monk
3
Dies ist keine direkte Antwort, wie andere bereits geantwortet haben, aber ich lade Sie ein, sich LogLifeCycle anzuschauen, um zu verstehen, was in Ihren Android-Apps in Bezug auf Lebenszyklen passiert.
Snicolas

Antworten:

965

Verwenden der Anwendungsklasse

Abhängig davon, was Sie in Ihrer Initialisierung tun, können Sie eine neue Klasse erstellen, die ApplicationIhren Initialisierungscode erweitert und in eine überschriebene onCreateMethode innerhalb dieser Klasse verschiebt.

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

Die onCreatein der Anwendungsklasse wird nur aufgerufen, wenn die gesamte Anwendung erstellt wurde, sodass die Aktivität bei Ausrichtung neu gestartet wird oder Änderungen der Tastatursichtbarkeit sie nicht auslösen.

Es wird empfohlen, die Instanz dieser Klasse als Singleton verfügbar zu machen und die Anwendungsvariablen, die Sie initialisieren, mithilfe von Gettern und Setzern verfügbar zu machen.

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 verursachen würden - wie z. B. Änderungen der Ausrichtung und der Sichtbarkeit der Tastatur - und diese in Ihrer Aktivität behandeln.

Fügen Sie zunächst den android:configChangesKnoten zum Manifestknoten Ihrer Aktivität hinzu

 <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">

Überschreiben Sie dann innerhalb der Aktivität die onConfigurationChangedMethode und rufen Sie setContentViewauf, um zu erzwingen, dass das GUI-Layout in der neuen Ausrichtung erneut ausgeführt wird.

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}
Reto Meier
quelle
17
Ich glaube nicht, dass der zweite Ansatz funktioniert. Ich versuchte es; eine Aktivität mit einem EditText. Ich habe dort Text geschrieben, die Ausrichtung geändert und der Text wurde entfernt / zurückgesetzt.
Ted
231
Wir hoffen, dass wir in Zukunft eine onRotate () -Methode sehen werden. Sich über solche Dinge überhaupt Sorgen machen zu müssen, ist - ehrlich gesagt - frustrierend.
Kelly Sutton
84
Beachten Sie, dass der Android Dev Guide davor warnt: Hinweis: Die Verwendung von ( android:configChanges) sollte vermieden und nur als letzter Ausweg verwendet werden. Weitere Informationen zur ordnungsgemäßen Behandlung eines Neustarts aufgrund einer Konfigurationsänderung finden Sie unter Behandeln von Laufzeitänderungen. Stattdessen scheinen sie es vorzuziehen, die Daten über Rotationsereignisse hinweg zu verwenden onSaveInstanceState Bundle. oder wie @ Jon-O erwähnt , onRetainNonConfigurationInstance.
Jeffro
19
Das ist eine schlechte Lösung, da sie nur auf derzeit bekannte Konfigurationsänderungen reagiert . Bei neueren Android-Versionen können andere Konfigurationsänderungen auftreten, die dieser Code nicht abfängt (da alle Konfigurationsänderungen im Manifest aufgelistet werden müssen). Die Lösung zum Speichern des Zustands onRetainNonConfigurationChangesist fehlertoleranter und unkomplizierter.
Bananeweizen
16
Ich denke, Sie sollten dieses Update auf 3.2 zu Ihrer Antwort hinzufügen , es ist ziemlich wichtig (nur mit diesem Problem konfrontiert) und es könnte übersehen werden.
Bigstones
185

Update für Android 3.2 und höher:

Achtung : Ab Android 3.2 (API-Level 13) ändert sich die "Bildschirmgröße" auch, wenn das Gerät zwischen Hoch- und Querformat wechselt. Wenn Sie also einen Neustart der Laufzeit aufgrund von Orientierungsänderungen bei der Entwicklung für API-Level 13 oder höher (wie durch die Attribute minSdkVersion und targetSdkVersion deklariert) verhindern möchten, müssen Sie den "screenSize"Wert zusätzlich zum "orientation"Wert angeben . Das heißt, Sie müssen erklären android:configChanges="orientation|screenSize". Wenn Ihre Anwendung jedoch auf API-Stufe 12 oder niedriger abzielt, behandelt Ihre Aktivität diese Konfigurationsänderung immer selbst (diese Konfigurationsänderung startet Ihre Aktivität nicht neu, selbst wenn sie auf einem Android 3.2-Gerät oder höher ausgeführt wird).

Gorm
quelle
1
Vielen Dank für diese Klarstellung, da mich ein Kommentar oben fast dazu gebracht hätte, mich damit zu befassen. Ich ziele derzeit auf API 8 ab und mein Code hat keine screenSize in configChanges und kann bestätigen, dass er auf dem Gerät, auf dem ICS ausgeführt wird, einwandfrei funktioniert (ohne sich neu auszurichten).
Carl
Vielen Dank für den Hinweis, ich hatte nur android: configChanges = "Orientierung | Bildschirmgröße" gesetzt, und das Umschalten der Orientierung stellte meine Aktivität wieder her, und für mein Leben konnte ich nicht herausfinden, warum!
Christopher Perry
5
Hinzufügen von android: configChanges sollte nur als letzter Ausweg verwendet werden . Erwägen Sie stattdessen die Verwendung von Fragmentsund setRetainInstance.
Simon Forsberg
Der entscheidende Punkt ist screenSizefür Android 3.2 und höher, der mein Problem gelöst hat. Danke!
Fantouch
127

Anstatt zu verhindern, onCreate()dass Bundle savedInstanceStatedas Ereignis vollständig ausgelöst wird, überprüfen Sie möglicherweise, ob das Ereignis an das Ereignis übergeben wird, um festzustellen, ob es null ist oder nicht.

Wenn ich zum Beispiel eine Logik habe, die ausgeführt werden soll, wenn die Activitywirklich erstellt wird, und nicht bei jeder Orientierungsänderung, führe ich diese Logik onCreate()nur dann aus, wenn die savedInstanceStateNull ist.

Ansonsten möchte ich immer noch, dass das Layout für die Ausrichtung richtig neu gezeichnet wird.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

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

Ich bin mir nicht sicher, ob dies die ultimative Antwort ist, aber es funktioniert für mich.

Nebel
quelle
6
und wo rettest du eigentlich den Zustand?
Ewoks
5
Das scheint für mich zu funktionieren und es scheint bei weitem die einfachste Methode zu sein. Ich stelle fest, dass Sie nur 4 Ups dafür haben (5 einschließlich meiner) gegenüber 373 für die Idee der Unterklassenanwendung, was mir weitaus komplizierter erscheint. Gibt es einen Nachteil dieser Methode?
Steve
4
Diese Lösung hat bei mir sehr gut funktioniert. Ich war in der Lage Intent serverintent = new Intent(MainActivity.this, MessageListener.class);und startService(serverintent);ein serverSocket = new ServerSocket(0xcff2);und Socket client = serverSocket.accept();mit einem zu erstellen BufferedReader(new InputStreamReader(client.getInputStream()));und konnte mein Android drehen und die Client / Server-Verbindung aktiv halten, aber die GUI drehen lassen. Laut Handbuch wird savedInstanceState beim Herunterfahren der letzten Aktivität initialisiert.
Fred F
3
Ich verstehe nicht, was ist der Haken? Dies funktioniert hervorragend und ist viel weniger komplex als alle anderen Lösungen.
RTF
3
Dies ist der richtige Weg, um es in Android zu tun. Die anderen Möglichkeiten, eine Rotation mit configChanges zu fangen, und all das, was sperrig, komplex und unnötig ist.
LukeWaggoner
99

Was ich getan habe...

im Manifest zum Aktivitätsabschnitt 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();
}
Irgendwer irgendwo
quelle
3
Zur Verdeutlichung: Mit meiner Implementierung können Sie jetzt eine variable Initialisierung in onCreate () durchführen, und onConfigurationChanged () wird einfach für die Bildschirmdrehung aufgerufen. Ihre Variablen sind jetzt von Bildschirmdrehungen isoliert ;-) nett und ez
Jemand irgendwo
2
Ich habe alles wie hier beschrieben gemacht, aber ich erhalte die NullPointerException, wenn ich versuche, nach dem Orientierungswechsel einen Knopf zu drücken. Was könnte falsch sein?
Finnboy11
5
Denken Sie daran, meine Antwort ist wie 3 Jahre alt und Android entwickelt sich weiter ... Simon - haben Sie einen Link zum Beispielcode? Das brauchen die Leute.
Jemand irgendwo
3
Bei der Warnung vor android: configChanges paraphrasiert @ SimonAndréForsberg eigentlich nur die Android-Dokumente . Die Behandlung von Laufzeitänderungen enthält detailliertere Informationen zu den Alternativen (einschließlich Beispielcode).
Leif Arne Storset
67

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

android:configChanges

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

android:configChanges="orientation"

und für das Öffnen oder Schließen der Tastatur würden Sie verwenden:

android:configChanges="keyboardHidden"

Wenn Sie beide verarbeiten möchten, können Sie sie einfach mit dem Pipe-Befehl wie folgt trennen.

android:configChanges="keyboardHidden|orientation"

Dadurch wird die onConfigurationChanged-Methode in jeder von Ihnen aufgerufenen Aktivität ausgelöst. Wenn Sie die Methode überschreiben, können Sie die neuen Werte übergeben.

Hoffe das hilft.

GregD
quelle
2
@ GregD Ich weiß, weshalb jetzt ein guter Zeitpunkt ist, es zu aktualisieren, um die Situation von heute widerzuspiegeln. Angesichts der Anzahl der positiven Stimmen, die diese Frage hat, wird immer noch auf andere Fragen zu SO verwiesen.
Simon Forsberg
48

Ich habe gerade diese Überlieferung entdeckt:

Für die Aktivität am Leben durch eine Orientierungsänderung zu halten, und Umgang mit ihm durch onConfigurationChanged, die Dokumentation und das Codebeispiel oben deuten darauf hin , dies in der Manifest - Datei:

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

Das hat den zusätzlichen Vorteil, dass es immer funktioniert.

Die Bonusüberlieferung ist, dass das Weglassen des keyboardHiddenlogisch erscheint, aber zu Fehlern im Emulator führt (zumindest für Android 2.1): Wenn Sie nur orientationangeben, wird der Emulator sowohl OnCreateals auch onConfigurationChangedmanchmal und nur zu OnCreateanderen Zeiten aufgerufen .

Ich habe den Fehler auf einem Gerät nicht gesehen, aber ich habe gehört, dass der Emulator für andere fehlerhaft ist. Es lohnt sich also zu dokumentieren.

Liudvikas Bukys
quelle
14
Achtung: Ab Android 3.2 (API-Level 13) ändert sich die "Bildschirmgröße" auch, wenn das Gerät zwischen Hoch- und Querformat wechselt. Wenn Sie also einen Neustart der Laufzeit aufgrund von Orientierungsänderungen bei der Entwicklung für API-Level 13 oder höher verhindern möchten: android: configChanges = "Orientierung | Tastaturversteckt | Bildschirmgröße"
Geltrude
Ja, der Emulator saugt viel Zeit. Sie können sich nicht darauf verlassen, dass Konfigurationsänderungen genau gemeldet werden.
IgorGanapolsky
Hinzufügen von android: configChanges sollte nur als letzter Ausweg verwendet werden . Erwägen Sie stattdessen die Verwendung von Fragmentsund setRetainInstance.
Simon Forsberg
38

Sie können auch die Methode der Android-Plattform verwenden, um Daten über Orientierungsänderungen hinweg beizubehalten: onRetainNonConfigurationInstance()und getLastNonConfigurationInstance().

Auf diese Weise können Sie Daten über Konfigurationsänderungen hinweg beibehalten, z. B. Informationen, die Sie möglicherweise von einem Serverabruf erhalten haben, oder etwas anderes, das in onCreateoder seitdem berechnet wurde , und gleichzeitig Android die Möglichkeit geben, die ActivityVerwendung der XML-Datei für die jetzt verwendete Ausrichtung neu zu gestalten .

Siehe hier oder hier .

Es sollte beachtet werden , dass diese Methoden jetzt veraltet sind (obwohl noch flexibler als sich Orientierungsänderung Handhabung , da die meisten der oben genannten Lösungen vorschlagen) mit der Empfehlung , dass jeder Schalter auf Fragmentsund verwenden Sie stattdessen setRetainInstance(true)auf jedem FragmentSie behalten möchten.

Jon O.
quelle
3
Ich denke wirklich, dass Fragmente und setRetainInstance der beste (und von Google empfohlene) Weg sind, dies zu tun, +1 für Sie und -1 für alle anderen. Hinzufügen von Android: configChanges sollte nur als letzter Ausweg verwendet werden
Simon Forsberg
32

Der Ansatz ist nützlich, bei Verwendung von Fragmenten jedoch unvollständig.

Fragmente werden normalerweise bei Konfigurationsänderungen neu erstellt. Wenn Sie dies nicht möchten, verwenden Sie

setRetainInstance(true); in den Konstruktoren des Fragments

Dadurch bleiben Fragmente während der Konfigurationsänderung erhalten.

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

Abdo
quelle
7
Einverstanden. Mit der neuesten Android-API scheinen Fragmente der richtige Weg zu sein, um damit umzugehen. Ich habe es selbst noch nicht ausprobiert, aber nach dem, was ich beim Lesen dieser Seite gesammelt habe , verschieben Sie im Grunde 99% dessen, was Sie in einer Aktivität implementiert haben, in eine Unterklasse eines Fragments und fügen dieses Fragment dann der Aktivität hinzu. Die Tätigkeit wird nach wie vor zerstört und auf dem Bildschirm Rotation neu erstellt werden, aber man kann sagen , speziell android nicht um das Fragment zu zerstören mit der setRetainInstance()Methode @Abdo erwähnt.
Brianmearns
25

Ich habe es einfach hinzugefügt

     android:configChanges="keyboard|keyboardHidden|orientation"

in der Manifest-Datei und hat keine onConfigurationChangedMethode in meiner Aktivität hinzugefügt .

Jedes Mal, wenn die Tastatur heraus- oder hineingleitet, passiert nichts .

bass.t
quelle
hinzugefügt <application ...android:configChanges="keyboard|keyboardHidden|orientation">und es funktioniert. Meine Einstellungen in build.gradle:minSdkVersion 15, compileSdkVersion 23, buildToolsVersion "23.0.2"
Junior Mayhé
19

Die onCreateMethode wird auch dann noch aufgerufen, wenn Sie die orientationvon Android ändern . Wenn Sie also alle umfangreichen Funktionen auf diese Methode umstellen, hilft Ihnen dies nicht weiter

Ganesh Krishna
quelle
18

Fügen Sie den folgenden Code in Ihr <activity>Tag ein Manifest.xml:

android:configChanges="screenLayout|screenSize|orientation"
Vaishali Sutariya
quelle
17
 onConfigurationChanged is called when the screen rotates. 
 (onCreate is no longer called when screen rotates due to manifest, see:  
 android:configChanges)

Welcher Teil des Manifests sagt "nicht anrufen onCreate()"?

Auch Google docs sagen Verwendung zu vermeiden android:configChanges(außer als letztes Mittel ) .... Aber dann die alternativen Methoden , die sie vorschlagen , alle DO Einsatz android:configChanges.

Ich habe die Erfahrung gemacht, dass der Emulator IMMER die onCreate()Rotation aufruft .
Aber die 1-2 Geräte, auf denen ich den gleichen Code ausführe ... nicht. (Ich bin mir nicht sicher, warum es einen Unterschied geben würde.)

Carol
quelle
16

Es ist sehr einfach, machen Sie einfach die folgenden Schritte:

<activity
    android:name=".Test"
    android:configChanges="orientation|screenSize"
    android:screenOrientation="landscape" >
</activity>

Das funktioniert bei mir:

Hinweis: Die Ausrichtung hängt von Ihrer Anforderung ab

ManiTeja
quelle
15

Änderungen, die im Android-Manifest vorgenommen werden müssen, sind:

android:configChanges="keyboardHidden|orientation" 

Ergänzungen innerhalb der Aktivität sind:

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
sumit pandey
quelle
15

Fügen Sie diese Zeile zu Ihrem Manifest hinzu: -

android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"

und dieser Ausschnitt zur Aktivität: -

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }
Parin Parikh
quelle
14

Es gibt verschiedene Möglichkeiten, dies zu tun:

Aktivitätsstatus speichern

Sie können den Aktivitätsstatus in speichern onSaveInstanceState.

@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}

und verwenden Sie dann die bundle, um den Status wiederherzustellen.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}

Behandeln Sie Orientierungsänderungen selbst

Eine andere Alternative besteht darin, die Orientierungsänderungen selbst vorzunehmen. Dies wird jedoch nicht als gute Praxis angesehen.

Fügen Sie dies Ihrer Manifestdatei hinzu.

android:configChanges="keyboardHidden|orientation"

für Android 3.2 und höher:

android:configChanges="keyboardHidden|orientation|screenSize"

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}

Drehung einschränken

Sie können Ihre Aktivität auch auf den Hoch- oder Querformatmodus beschränken, um eine Drehung zu vermeiden.

Fügen Sie dies dem Aktivitäts-Tag in Ihrer Manifest-Datei hinzu:

        android:screenOrientation="portrait"

Oder implementieren Sie dies programmgesteuert in Ihrer Aktivität:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Piyush
quelle
11

Die Art und Weise, wie ich dies gefunden habe, besteht darin, die onRestoreInstanceStateund die onSaveInstanceStateEreignisse zu verwenden, um etwas in der zu speichern Bundle(auch wenn Sie keine gespeicherten Variablen benötigen , fügen Sie einfach etwas dort ein, damit das Bundlenicht leer ist). onCreateÜberprüfen Sie dann auf der Methode, ob das Bundleleer ist, und führen Sie die Initialisierung durch. Wenn nicht, führen Sie die Initialisierung durch.

Shaun
quelle
11

Auch wenn es nicht "der Android-Weg" ist, habe ich sehr gute Ergebnisse erzielt, indem ich Orientierungsänderungen selbst vorgenommen und die Widgets einfach in einer Ansicht neu positioniert habe, um die geänderte Orientierung zu berücksichtigen. Dies ist schneller als jeder andere Ansatz, da Ihre Ansichten nicht gespeichert und wiederhergestellt werden müssen. Es bietet dem Benutzer auch eine nahtlosere Benutzererfahrung, da die neu positionierten Widgets genau dieselben Widgets sind, die nur verschoben und / oder in der Größe geändert wurden. Auf diese Weise kann nicht nur der Modellstatus, sondern auch der Ansichtsstatus beibehalten werden.

RelativeLayoutkann manchmal eine gute Wahl für eine Ansicht sein, die sich von Zeit zu Zeit neu orientieren muss. Sie geben lediglich eine Reihe von Hochformat-Layout-Parametern und eine Reihe von Landschafts-Layout-Parametern mit jeweils unterschiedlichen relativen Positionierungsregeln für jedes untergeordnete Widget an. Dann übergeben Sie in Ihrer onConfigurationChanged()Methode die entsprechende an einen setLayoutParams()Anruf für jedes Kind. Wenn eine untergeordnete Steuerung selbst intern neu ausgerichtet werden muss, rufen Sie einfach eine Methode für dieses untergeordnete Element auf, um die Neuausrichtung durchzuführen. Das Kind in ähnlicher Weise ruft Methoden auf eines seiner untergeordneten Steuerelemente , die interne Neuausrichtung benötigen, und so weiter.

Carl
quelle
Ich würde gerne einen Beispielcode dafür sehen, scheint brillant!
Henrique de Sousa
8

Jedes Mal, wenn der Bildschirm gedreht wird, wird die geöffnete Aktivität beendet und onCreate () wird erneut aufgerufen.

1. Sie können eine Aktion ausführen, um den Aktivitätsstatus zu speichern, wenn der Bildschirm gedreht wird, sodass Sie alle alten Inhalte wiederherstellen können, wenn die Aktivität onCreate () erneut aufgerufen wird. Verweisen Sie auf diesen Link

2. Wenn Sie einen Neustart der Aktivität verhindern möchten, fügen Sie einfach die folgenden Zeilen in Ihre Datei manifest.xml ein.

  <activity android:name=".Youractivity"
  android:configChanges="orientation|screenSize"/>
Mansuu ....
quelle
7

Sie müssen die onSavedInstanceState-Methode verwenden, um den gesamten Wert des Parameters is hased is bundle zu speichern

@Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outPersistentState.putBoolean("key",value);
    }

und verwenden

@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        savedInstanceState.getBoolean("key");
    } 

Um den Wert für die Anzeige von Objekten abzurufen und festzulegen, werden die Bildschirmdrehungen verarbeitet

koteswara DK
quelle
Dies erfordert API Level 22.
Mohammad Afrashteh
6

Hinweis: Ich poste diese Antwort, wenn jemand in Zukunft das gleiche Problem wie ich hat. Für mich war die folgende Zeile nicht genug:

android:configChanges="orientation"

Beim Drehen des Bildschirms wurde die Methode `onConfigurationChanged (Configuration newConfig) nicht aufgerufen.

Lösung: Ich musste auch "screenSize" hinzufügen, auch wenn das Problem mit der Ausrichtung zu tun hatte. Fügen Sie in der Datei AndroidManifest.xml - Folgendes hinzu:

android:configChanges="keyboardHidden|orientation|screenSize"

Implementieren Sie dann die Methode onConfigurationChanged(Configuration newConfig)

iHank
quelle
5

Fügen Sie im Aktivitätsbereich von manifestFolgendes hinzu:

android:configChanges="keyboardHidden|orientation"
Richard K Maleho
quelle
5

Fügen Sie diese Zeile im Manifest hinzu: android:configChanges="orientation|screenSize"

Vikramsinh Gaikwad
quelle
4

Die Leute sagen, dass Sie verwenden sollten

android:configChanges="keyboardHidden|orientation"

Die beste und professionellste Möglichkeit, mit Rotation in Android umzugehen, ist die Verwendung der Loader-Klasse. Es ist keine berühmte Klasse (ich weiß nicht warum), aber es ist viel besser als die AsyncTask. Weitere Informationen finden Sie in den Android-Tutorials in den Android-Kursen von Udacity.

Als andere Möglichkeit können Sie die Werte oder Ansichten natürlich mit onSaveInstanceState speichern und mit onRestoreInstanceState lesen. Es liegt wirklich an dir.

Das Ö
quelle
Ja, lassen Sie uns zusätzlichen Code hinzufügen, um "professionell" auszusehen. Oder wie wäre es, wenn Sie sich einfach an die schnelle, einfache, wahre und bewährte Methode mit dem Attribut configurationChanges halten.
AndroidDev
3

Nach einer Weile des Versuchs und Irrtums fand ich eine Lösung, die in den meisten Situationen meinen Bedürfnissen entspricht. Hier ist der Code:

Manifest Konfiguration:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.pepperonas.myapplication">

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

Hauptaktivität:

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";

    private Fragment mFragment;

    private int mSelected = -1;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate  " + "");

        // null check not realy needed - but just in case...
        if (savedInstanceState == null) {

            initUi();

            // get an instance of FragmentTransaction from your Activity
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

            /*IMPORTANT: Do the INITIAL(!) transaction only once!
            * If we call this everytime the layout changes orientation,
            * we will end with a messy, half-working UI.
            * */
            mFragment = FragmentOne.newInstance(mSelected = 0);
            fragmentTransaction.add(R.id.frame, mFragment);
            fragmentTransaction.commit();
        }
    }


    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d(TAG, "onConfigurationChanged  " +
                   (newConfig.orientation
                    == Configuration.ORIENTATION_LANDSCAPE
                    ? "landscape" : "portrait"));

        initUi();

        Log.i(TAG, "onConfigurationChanged - last selected: " + mSelected);
        makeFragmentTransaction(mSelected);
    }


    /**
     * Called from {@link #onCreate} and {@link #onConfigurationChanged}
     */
    private void initUi() {
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate  instanceState == null / reinitializing..." + "");
        Button btnFragmentOne = (Button) findViewById(R.id.btn_fragment_one);
        Button btnFragmentTwo = (Button) findViewById(R.id.btn_fragment_two);
        btnFragmentOne.setOnClickListener(this);
        btnFragmentTwo.setOnClickListener(this);
    }


    /**
     * Not invoked (just for testing)...
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME!!!");
    }


    /**
     * Not invoked (just for testing)...
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME, AS WELL!!!");
    }


    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume  " + "");
    }


    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause  " + "");
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy  " + "");
    }


    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btn_fragment_one:
                Log.d(TAG, "onClick btn_fragment_one " + "");
                makeFragmentTransaction(0);
                break;

            case R.id.btn_fragment_two:
                Log.d(TAG, "onClick btn_fragment_two " + "");
                makeFragmentTransaction(1);
                break;

            default:
                Log.d(TAG, "onClick  null - wtf?!" + "");
        }
    }


    /**
     * We replace the current Fragment with the selected one.
     * Note: It's called from {@link #onConfigurationChanged} as well.
     */
    private void makeFragmentTransaction(int selection) {

        switch (selection) {
            case 0:
                mFragment = FragmentOne.newInstance(mSelected = 0);
                break;
            case 1:
                mFragment = FragmentTwo.newInstance(mSelected = 1);
                break;
        }

        // Create new transaction
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack
        transaction.replace(R.id.frame, mFragment);

        /*This would add the Fragment to the backstack...
        * But right now we comment it out.*/
        //        transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }

}

Und Beispielfragment:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * @author Martin Pfeffer (pepperonas)
 */
public class FragmentOne extends Fragment {

    private static final String TAG = "FragmentOne";


    public static Fragment newInstance(int i) {
        Fragment fragment = new FragmentOne();
        Bundle args = new Bundle();
        args.putInt("the_id", i);
        fragment.setArguments(args);
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView  " + "");
        return inflater.inflate(R.layout.fragment_one, container, false);
    }

}

Kann auf Github gefunden werden .

Martin Pfeffer
quelle
3

Verwenden Sie den orientationListener, um verschiedene Aufgaben mit unterschiedlicher Ausrichtung auszuführen.

@Override
public void onConfigurationChanged(Configuration myConfig) 
{
    super.onConfigurationChanged(myConfig);
    int orient = getResources().getConfiguration().orientation; 
    switch(orient) 
    {
       case Configuration.ORIENTATION_LANDSCAPE:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    break;
       case Configuration.ORIENTATION_PORTRAIT:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    break;
       default:
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
}
Akshay Paliwal
quelle
3

Geben Sie diesen Code in Ihr ActivityIn ein Android Manifest.

android:configChanges="orientation"

Dadurch wird Ihre Aktivität nicht neu gestartet, wenn Sie die Ausrichtung ändern würden.

Pratik Dasa
quelle
2
@Mavamaarten Wahrscheinlich, weil, wie andere darauf hingewiesen haben, es eine schlechte Praxis ist und zehn andere Antworten dies bereits behandelt haben.
MikkoP
3

Korrigieren Sie die Bildschirmausrichtung (Quer- oder Hochformat) in AndroidManifest.xml

android:screenOrientation="portrait" oder android:screenOrientation="landscape"

dafür wird deine onResume()Methode nicht aufgerufen.

Brajendra Pandey
quelle
5
Wie zum Teufel ist es eine Antwort, etwas zu reparieren? Warum können sich unsere Geräte drehen, wenn wir Benutzer sperren, die sie verwenden?
Reinherd
3

Eine der besten Komponenten der von Google eingeführten Android-Architektur erfüllt alle Anforderungen von ViewModel.

Damit sollen UI-bezogene Daten im Lebenszyklus gespeichert und verwaltet werden. Außerdem können Daten überleben, wenn sich der Bildschirm dreht

class MyViewModel : ViewModel() {

Bitte beachten Sie dies: https://developer.android.com/topic/libraries/architecture/viewmodel

Android Geek
quelle