Dlaczego nie używać zawsze android: configChanges = "keyboardHidden | Orientacja"?

178

Zastanawiałem się, dlaczego nie używać android:configChanges="keyboardHidden|orientation"w każdej (prawie każdej;)) czynności?

Dobra:

  • Nie musisz się martwić, że Twoja aktywność została zmieniona
  • to jest szybsze

Niezbyt miły:

  • trzeba zmienić układy, jeśli zależą one od rozmiaru ekranu (np. układy z dwiema kolumnami lub więcej)

Zły:

  • brak elastycznego sposobu na różne układy w różnych orientacjach
  • nie tak dobrze, gdy używa się fragmentów

Ale jeśli nie używamy różnych układów, dlaczego nie?

Mikooos
źródło
6
Powinieneś również wyjaśnić, co Twoim zdaniem robi keyboardHidden | Orientacja
Blundell,
To uniemożliwia korzystanie z natywnej obsługi określonych zmian konfiguracji i pozwala aplikacji obsłużyć to, prawda?
Mikooos,
2
Dlatego ta opcja jest dostępna, jeśli wiesz, co robisz (bez zmian w zasobach), użyj jej.
Pointer Null
dlaczego jest szybszy niż używanie ScreenSize?
batmaci

Odpowiedzi:

334

Szybkie tło

Domyślnie, gdy pewne kluczowe zmiany konfiguracji mają miejsce w systemie Android (typowym przykładem jest zmiana orientacji), system Android całkowicie ponownie uruchamia działające działanie, aby pomóc mu dostosować się do takich zmian.

Definiując android:configChanges="keyboardHidden|orientation"w pliku AndroidManifest, mówisz systemowi Android: „Proszę nie resetować ustawień domyślnych po wyjęciu klawiatury lub obróceniu telefonu; chcę sobie z tym poradzić samodzielnie. Tak, wiem, co robię "

Czy to dobra rzecz? Wkrótce zobaczymy ...

Bez obaw?

Jednym z plusów, od których zaczynasz, jest:

Nie musisz się martwić, że Twoja aktywność została zmieniona

W wielu przypadkach ludzie błędnie uważają, że kiedy mają błąd, który jest generowany przez zmianę orientacji („rotację”), mogą go po prostu naprawić, wprowadzając android:configChanges="keyboardHidden|orientation".

Jednak android: configChanges = "keyboardHidden | Orientacja" to nic innego jak bandaid. W rzeczywistości istnieje wiele sposobów wywołania zmiany konfiguracji. Na przykład, jeśli użytkownik wybierze nowy język (tj. Zmienił się język), Twoja aktywność zostanie wznowiona w taki sam sposób, jak w przypadku zmiany orientacji. Jeśli chcesz, możesz wyświetlić listę wszystkich różnych typów zmian konfiguracyjnych .

Edycja : co ważniejsze, jak wskazuje hackbod w komentarzach, Twoja aktywność zostanie również wznowiona, gdy aplikacja będzie działać w tle, a Android zdecyduje się zwolnić trochę pamięci, zabijając ją. Gdy użytkownik wróci do Twojej aplikacji, system Android podejmie próbę ponownego uruchomienia działania w taki sam sposób, jak w przypadku innej zmiany konfiguracji. Jeśli sobie z tym nie poradzisz - użytkownik nie będzie zadowolony ...

Innymi słowy, używanie android:configChanges="keyboardHidden|orientation"nie jest rozwiązaniem „zmartwień”. Właściwy sposób to zakodować swoje działania tak, aby były zadowolone z każdego restartu systemu Android, który rzuca na nich. To dobra praktyka, która pomoże ci w dalszej drodze, więc przyzwyczaj się do niej.

Kiedy więc powinienem go używać?

Jak wspomniałeś, istnieje wyraźna zaleta. Nadpisanie domyślnej zmiany konfiguracji dla rotacji przez samodzielną obsługę przyspieszy działanie. Jednak ta prędkość ma swoją cenę wygody.

Mówiąc prościej, jeśli używasz tego samego układu zarówno w orientacji pionowej, jak i poziomej, jesteś w dobrej formie, wykonując nadpisanie. Zamiast pełnego ponownego wczytywania aktywności, widoki po prostu się przesuwają, aby wypełnić pozostałą przestrzeń.

Jeśli jednak z jakiegoś powodu użyjesz innego układu, gdy urządzenie jest ustawione poziomo, fakt, że Android ponownie ładuje Twoją aktywność, jest dobry, ponieważ następnie załaduje prawidłowy układ. [Jeśli używasz nadpisywania w takim działaniu i chcesz wykonać magiczną zmianę układu w czasie wykonywania ... cóż, powodzenia - nie jest to proste]

Szybkie podsumowanie

Jeśli android:configChanges="keyboardHidden|orientation"tak, to z niego korzystaj. Ale PROSZĘ koniecznie przetestować, co się dzieje, gdy coś się zmieni, ponieważ zmiana orientacji nie jest jedynym sposobem na uruchomienie pełnego ponownego uruchomienia działania.

yydl
źródło
50
Warto dodać, że brak obsługi restartowanej aktywności oznacza, że ​​masz większe problemy niż po prostu nieobsługiwanie mniej powszechnych zmian konfiguracji. Zastosowane tutaj ponowne uruchomienie działania jest dokładnie tym samym mechanizmem, co sposób, w jaki Android przywraca Twoją aktywność do poprzedniego stanu, gdy aplikacja zostanie zabita w tle. Jeśli więc nie zrobisz tego poprawnie, Twoi użytkownicy doświadczą, że Twoja aplikacja nie powróci w sposób losowy, gdy powrócą do niej z tła, w zależności od tego, czy proces został zabity. A więc ogromna korzyść: zapewnia prawidłowe ponowne uruchomienie aplikacji.
hackbod
14
Od Androida 3.x nie zapomnij dodać „screenSize” ---------- android: configChanges = [„mcc”, „mnc”, „locale”, „touchscreen”, „keyboard”, „keyboardHidden”, „navigation”, „screenLayout”, „fontScale”, „uiMode”, „orientacja”, „screenSize”, „smallestScreenSize”]
Michael Biermann
1
Zauważyłem, że kiedy używasz atrybutu configChanges, twoja aplikacja ignoruje również funkcję blokady orientacji. Jak możesz to rozwiązać? jeśli znasz odpowiedź, napisz ją tutaj: stackoverflow.com/questions/24000361/ ...
programista Androida
4
Please don't do the default reset when the keyboard is pulled outnigdy nie widziałem ponownego uruchomienia działania klawiatury !
Muhammad Babar
cóż, sporadyczne ponowne uruchomienia są w porządku, moim zdaniem ... configChanges obsługuje większość przypadków dla mnie ... no może w innych typach aplikacji może to być problem, ale to naprawdę zależy ....
Renetik
2

Z mojego punktu widzenia: jeśli układ jest taki sam zarówno w trybie poziomym, jak i pionowym - możesz również wyłączyć jeden z dwóch w swojej aplikacji.

Powodem, dla którego to stwierdzam, jest to, że jako użytkownik oczekuję, że aplikacja zapewni mi pewne korzyści, gdy zmienię orientację. Jeśli nie ma znaczenia, jak trzymam telefon, nie potrzebuję wyboru.

Weźmy na przykład aplikację, w której masz ListView, i po kliknięciu ListItem chcesz wyświetlić szczegółowy widok tego elementu. W krajobrazie można to zrobić, dzieląc ekran na dwie części, mając ListView po lewej stronie i szczegółowy widok po prawej. W trybie Portret miałbyś listę na jednym ekranie, a następnie zmienić ekran na widok szczegółowy po wybraniu ListItem. W takim przypadku zmiana orientacji ma sens, podobnie jak inne układy.

kaspermoerch
źródło
4
Tak, zdecydowaliśmy się na to w wersji 1.0 naszej aplikacji, aby dopasować się do naszej wersji Apple. Został przedstawiony TYLKO w portrecie. Co wyglądało świetnie na moim Droid X, dokładnie dopasowaliśmy zachowanie klawiatury wyskakującej do wersji IOS. Następnie dyrektor finansowy zainstalował aplikację na swoim droidzie, obrócił ją na bok i odsunął klawiaturę. Ups. Chodzi o to, że Android jest otwartą platformą i naprawdę nie możesz przewidzieć konfiguracji sprzętu ani tego, co użytkownik będzie chciał z nim zrobić, więc na wszelki wypadek prawdopodobnie powinieneś obsługiwać obie (wszystkie) orientacje.
Tevo D
1
Co, nawiasem mówiąc, przesłoniło nasze ustawienie tylko portretowe, ponieważ zasadniczo w sprzęcie krajobraz był wtedy normalną, a nie alternatywną orientacją. Co NAPRAWDĘ zepsuło nasz układ :( i było dość żenujące, mając poważną wadę w ciągu kilku sekund od zainstalowania aplikacji
Tevo D
1
Dlaczego starałeś się, aby działał dokładnie tak, jak iOS? :(
FunkTheMonk
7
@FunkTheMonk Niestety żyjemy w świecie, w którym biznesmeni podejmują decyzje techniczne. Nawet jeśli się temu sprzeciwiasz, w połowie przypadków oni i tak myślą, że mają rację. I kontrolują twoją wypłatę.
StackOverflowed
2
Używanie tylko jednego układu nie oznacza, że ​​ekran będzie wyglądał tak samo po obróceniu. Dobrze ustrukturyzowany układ XML spowoduje automatyczne przesuwanie rzeczy, tak aby działały dobrze w rozsądnych wymiarach, a użytkownicy to docenią.
Melinda Green
-1

Nie rozumiem, dlaczego .... sporadyczne ponowne uruchamianie jest moim zdaniem w porządku ... configChanges obsługuje większość przypadków dla mnie ... cóż, może w niektórych typach aplikacji może to być problem, ale tak naprawdę zależy to od typu aplikacji i sposobu jej przywracania stan, gdy aplikacja uruchomi się ponownie ... Kiedy jedna z moich aplikacji uruchomi się ponownie, użytkownik jest zalogowany ponownie i ostatnia aktywność otwiera się przez mój kod, a użytkownik jus traci kilka kroków, aby wrócić do miejsca, w którym był, ale nie jest to wielka sprawa. jakiś stan jest zawsze przywracany po ponownym uruchomieniu. Kiedy aktywność została wznowiona, musiało to oznaczać, że aplikacja nie była używana lub coś ... więc nie ma problemu ... Na przykład w grze może to być problem lub w innej aplikacji, której nie znam ...

Mówię, że kiedy robisz to w ten sposób, aplikacje działają dobrze w normalnych okolicznościach. A kod jest znacznie bardziej czytelny bez mnóstwa logiki potrzebnej do zapisywania i przywracania, gdzie możesz po prostu wprowadzać nowe błędy i utrzymywać go przez cały czas ... upewnij się, że jeśli android wyłączy się i zabije okno aplikacji, traci kontekst i zaczyna się od nowa, ale zdarza się to tylko w wyjątkowych sytuacjach i na nowszych urządzeniach, jak sądzę, jest to coraz rzadsze ...

Więc zabij mnie, ale z powodzeniem używam tego w różnych aplikacjach ... android: configChanges = "locale | keyboard | keyboardHidden | Orientation | screenLayout | uiMode | screenSize | smallestScreenSize" Ale rozumiem, że w przypadku niektórych specjalnych aplikacji może to nie być dobry sposób, ale większość aplikacji może z tym żyć.

Renetik
źródło
Cześć, czy ktoś znający się na tym temacie może zajrzeć do mojego wątku: stackoverflow.com/questions/35941585/…? Rozpaczliwie potrzebuję pomocy.
Luke Allison,
Powinieneś w pełni wspierać zapisywanie / wznawianie działań ... obsługa tego w celu rotacji nie różni się ... Mówisz, że tracisz kilka kroków ... jeśli robisz to poprawnie, nie tracisz żadnych kroków i przywracasz dokładnie miejsce, w którym skończył użytkownik ... nawet po restarcie urządzenia.
HaMMeReD
młotkowany Nie wiem, o czym mówisz, ale mówię, że kiedy robisz to w ten sposób, aplikacje działają dobrze w normalnych warunkach. A kod jest znacznie bardziej czytelny bez mnóstwa logiki potrzebnej do zapisywania i przywracania, gdzie możesz po prostu wprowadzać nowe błędy i utrzymywać go przez cały czas ... upewnij się, że jeśli android wyłączy się i zabije okno aplikacji, traci kontekst i zaczyna się od nowa, ale zdarza się to tylko w wyjątkowych sytuacjach i na nowszych urządzeniach, wierzę, że jest to coraz rzadsze ...
Renetik
Ignorowanie przestrzegania umowy o działanie (zapisywanie / przywracanie stanu) jest złą praktyką i jest to ogólnie straszna rada. Spróbuj przetestować przed śmiercią procesu i zobacz, dokąd prowadzi Twoja aplikacja. Takie zachowanie jest całkowicie standardową „normalną sytuacją”, jeśli użytkownik korzysta z co najmniej 2-3 aplikacji na swoim telefonie i przełącza się między nimi.
EpicPandaForce
-3

Tak, myślę, że wstrzymanie będzie szybsze niż zwolnienie odtwarzacza. Jednak nadal mam przerwę.

Znalazłem rozwiązanie, które nie wstrzymuje utworu.

Określ w manifeście, że będziesz obsługiwać zmianę konfiguracji dla orientacji ekranu, a następnie użyj metody onConfigurationChanged, aby załadować plik układu. Robiąc to w logCat, widzę, że onPause, onCreate i onResume nie są wywoływane, a zatem utwór nie jest wstrzymywany.

  1. zaktualizuj manifest, aby obsłużyć orientację.

    android:configChanges="orientation|screenSize"
  2. dodaj ten kod

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub      
        super.onConfigurationChanged(newConfig);        
        setContentView(R.layout.activity_main);
    }
Raul
źródło
Powinieneś używać usługi do odtwarzania muzyki. Poważnie, mówisz ludziom, aby dodawali kod, który nadal zawiera „// TODO Automatycznie wygenerowany kod metody”. Niechlujne rozwiązanie. To też nie zadziała dobrze, będziesz musiał ponownie powiązać wszystkie swoje odniesienia, a jeśli tego nie zrobisz, będą w najlepszym przypadku nieprzewidywalne.
HaMMeReD