Android, jak nie zniszczyć aktywności, gdy obracam urządzenie?

81

Mam aplikację, która działa tylko w trybie portretowym i wprowadziłem zmiany w moim pliku manifestu dla każdego działania na orientację portretową. Ale kiedy obracam urządzenie, aktywność odtwarza się ponownie. Jak nie zniszczyć aktywności?

Wasilij
źródło
1
Jest to często odradzane, możesz spróbować programowo ustawić orientację aplikacji za pomocą czegoś takiego: setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
stealthcopter
7
Dlaczego miałoby to być przeciwko? Powiedzmy, że mamy usługę, której uruchomienie trwa 2 sekundy. Jeśli aktywność niszczy się za każdym razem, ta usługa działa za każdym razem, podczas gdy ja potrzebuję tylko raz.
Mohamed Mansour,

Odpowiedzi:

131

Dla API 12 i starszych : dodaj

android:configChanges="orientation"

Dodaj „screenSize”, jeśli celujesz w interfejs API 13 lub nowszy, ponieważ przy każdej zmianie orientacji zmienia się również rozmiar ekranu, w przeciwnym razie nowe urządzenia będą nadal niszczyć Twoją aktywność. Zobacz odpowiedź Egg poniżej, aby uzyskać więcej informacji na temat korzystania z opcji „screenSize”

android:configChanges="orientation|screenSize"

do swojej aktywności w AndroidManifest.xml. W ten sposób Twoja aktywność nie zostanie automatycznie ponownie uruchomiona. Więcej informacji znajdziesz w dokumentacji

Wyzwanie przyjęte
źródło
Czynność jest ponownie uruchamiana. Nie wiem, jaki jest sens robienia wszystkich rzeczy, które należy wykonać, gdy działanie się obraca, nawet jeśli nie jest wirtualne. Czy istnieje sposób na wyłączenie tych komunikatów, które czujnik wysyła do systemu operacyjnego o rotacji lub coś w tym rodzaju, aby naprawić ten problem z jego katalogu głównego?
Vasil
6
na jakim urządzeniu programujesz? pamiętać, że na przykład wysunięcie klawiatury może również ponownie uruchomić działalność ... (jeśli to jest powód zestaw confChanges „Klawiatura | keyboardHidden | orientacji”)
2
Spowoduje to wyłączenie zmiany układu. Jak to naprawić?
Remian8985
1
To rozwiązanie rozwiązuje problem niszczenia i tworzenia, ale jak radzić sobie ze zmianami układu. Chodzi mi o to, że po zmianie orientacji ładuję odpowiedni układ.
sandeepmaaram
Czy istnieje sposób na programowe ustawienie parametru android: configChanges, a nie w pliku manifestu?
CodyF
108

Z oficjalnego dokumentu flurin powiedział:

Uwaga: jeśli aplikacja jest przeznaczona dla interfejsu API na poziomie 13 lub wyższym (zgodnie z deklaracją w atrybutach minSdkVersion i targetSdkVersion), należy również zadeklarować konfigurację „screenSize”, ponieważ zmienia się ona również, gdy urządzenie przełącza się między orientacją pionową i poziomą.

Jeśli więc Twoja aplikacja jest skierowana na poziom interfejsu API 13 lub wyższy, należy zamiast tego ustawić tę konfigurację:

android:configChanges="orientation|screenSize"

jajko
źródło
4
Dziękuję bardzo! Wszystkie inne odpowiedzi pomijają tę część, w której API poziom 13 wprowadza ten screenSize. Właśnie uratowałeś mi życie! :)
Tamás Barta
1
@egg Dziękuję ciuuuuuu! :) To pomogło!
KarenAnne
1
Świetna wskazówka, że ​​trudno jest nadążać za dokumentacją, gdy robisz to w niepełnym wymiarze godzin.
wallerjake
1
+1 Miły dotyk człowieka. Dziękujemy za udostępnienie nam tego rozwiązania. Uratowałeś mój dzień. Dzięki;)
Simon Dorociak
9

Właściwe rozwiązanie to

android:configChanges="orientation|screenSize"

Dokumentacja Androida:

Aktualnie dostępny rozmiar ekranu uległ zmianie. Oznacza to zmianę aktualnie dostępnego rozmiaru w stosunku do aktualnego współczynnika proporcji, więc zmieni się, gdy użytkownik przełączy się z trybu poziomego na pionowy. Jeśli jednak aplikacja jest przeznaczona dla interfejsu API na poziomie 12 lub niższym, aktywność zawsze sama obsługuje tę zmianę konfiguracji (ta zmiana konfiguracji nie powoduje ponownego uruchomienia działania, nawet jeśli jest uruchomiona na urządzeniu z systemem Android 3.2 lub nowszym). *

er_benji
źródło
5

Trochę to pogmatwałem, a potem powtórzyłem, że w pliku manifestu umieszczałem configChanges na poziomie aplikacji, a nie na poziomie aktywności. Oto jak wygląda kod, gdy działa poprawnie.

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
                  android:configChanges="orientation|screenSize|keyboardHidden">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity> 
</application> 
superheron
źródło
2
Powinieneś udostępnić kod w swoim poście zamiast obrazu.
Jules Dupont,
Proszę edytować swój post i pokazać rzeczywisty kod oczywisty jako tekst zamiast screenów. Inni nie mogą kopiować i wklejać z Twoich obrazów. Zobacz szczegóły. Dziękuję Ci.
Pang
1

Teraz, gdy Android obsługuje podzielony ekran („wiele okien” w języku Androida), prawdopodobnie będziesz chciał dodać również screenSize | smallestScreenSize | screenLayout | orientację. Aby obsłużyć rotację i podzielony ekran, potrzebujesz czegoś takiego w Androidzie: configChanges

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
                  android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity> 
</application>
pkoepke
źródło
-1

napisz w manifest:

android:configChanges="orientation|screenSize|keyboardHidden"

i zastąp to w działaniu, które rozwiązało Twój problem:

 @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
}
mojtaba
źródło
5
Dlaczego miałoby zastępować metodę onConfigurationChanged i wywoływać oryginalną implementację, robiąc cokolwiek pożytecznego?
ricosrealm