Najlepsza praktyka obsługi zmiany orientacji: Android

Przechodziłem przez różne praktyki, aby poradzić sobie ze zmianą orientacji za pomocą wątków i AsyncTask. Natknąłem się na następujące rozwiązania:

  1. Attach-detach model: dołączanie i odłączanie aktywności do wątków i AsyncTask przy zachowaniu ich instancji. (Źródło: 1, 2)

  2. Fragment bezgłowy: używanie fragmentu Bezgłowego do wykonywania wszystkich operacji związanych z wątkiem i zachowywanie jego instancji na zmiana konfiguracji. (Źródło: 1, 2)

Czy są jakieś inne sposoby radzenia sobie z tym scenariuszem? Jaka jest zalecana praktyka? Pytam o to, ponieważ nie mogłem znaleźć ogólnego rozwiązania nigdzie w dokumentach Android.

Author: Community, 2013-12-11

6 answers

Niektóre streszczenia

Istnieje kilka metod wymienionych powyżej, które są dobrymi praktykami, ale pomyślałem, że mogę je podsumować krótkimi wyjaśnieniami. Poniżej znajdują się niektóre z najpopularniejszych bibliotek używanych obecnie do sieci http, asynchronicznej pracy / wątku i buforowania.

Mój obecny projekt (tylko preferencje)

Ja osobiście obecnie używam Otto, Ładowarki, Volley, Ormlite , oraz stos sieciowy na podstawie Apache i Service s. mam nadzieję, że stos sieci w pewnym momencie zastąpi albo , Retrofit , a może w końcu Robospice .

Jaosobiście Bardzo lubię Otto i Volley


RoboSpice (Modular)

  • https://github.com/octo-online/robospice
  • http://www.youtube.com/watch?v=ONaD1mB8r-A
  • a plugin / modular approach do zadań długotrwałych
  • to jest jak "swiss-army-knife" bibliotek, ale musisz wiedzieć, co robi każde narzędzie.
  • obsługuje wywołania REST
  • utrzymuje dane poprzez orientację i inne zmiany
  • Może obsługiwać buforowanie dysku i pamięci)]}
  • współpracuje z różnymi bibliotekami HTTP i bibliotekami persistence (Gson, Jackson, Spring, OkHttp, i wiele z poniższych bibliotek)
  • beta Dla Ormlite wsparcie, I myśl

Retrofit (REST)

Volley (Networking data & Images)

Picasso (images)

Ładowarki (Android)

  • dobrze obsługiwane
  • persist poprzez zmianę orientacji i zapisywanie / ładowanie stanu fragmentu
  • może być trudne do poprawienia
  • brak buforowania

AsyncTask (Android)

  • prosty sposób na pracę w tle z wątku UI
  • muszą być anulowane i uważać na zadania, które powracają po zburzeniu aktywności lub fragmentu.

Otto (wydarzenie bus)

  • https://github.com/square/otto
  • Szyna zdarzeń, która ułatwia pracę a-sync między komponentami i fragmentami
  • Bardzo potężna @Produce zdolność zachowuje ostatnie wydarzenie i może produkować je na żądanie dla każdego nowego zainteresowanego Abonenta autobusu

Fragmenty Bezgłowe (?)

  • osobiście nigdy nie widziałem tego używanego innego niż tutoriale Vogelli, więc nie jestem pewien, co do tego jeden.

Service (Android)

  • the old school way
  • ultimate control, you must do everything yourself
  • W tym celu należy skontaktować się z Działem Obsługi Klienta.]}
  • przeprowadź paczki przez Intenty
 43
Author: pjco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-19 06:13:54

Dlaczego nie spróbujesz Loaders, w szczególności AsyncTaskLoader? Są one dostępne dla Pre-Honeycomb poprzez Support Library i doskonale pasują do cyklu życia aktywności / fragmentu. Oto oficjalne podsumowanie:

  • są dostępne dla każdego działania i fragmentu.
  • zapewniają asynchroniczne ładowanie danych.
  • monitorują źródło swoich danych i dostarczają nowe wyniki, gdy zmienia się zawartość.
  • automatycznie łączą się z kursor ostatniego loadera podczas odtwarzania po zmianie konfiguracji. W ten sposób nie muszą ponownie wyszukiwać swoich danych.
 7
Author: a.ch.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-17 15:45:53

W rzeczywistości używamy Biblioteki RoboSpice. Działa w Serwisie z dostarczaniem tylko obiektów RequestListeners.

Problem z pierwszym podejściem (utrzymywanie odniesień między Asynktaskiem) polega na tym, że prawdopodobnie możesz wygenerować wycieki pamięci, ponieważ gdy Twoje Asynktaski przechowują odniesienia do Twoich działań, nie będą one zbierane. Obserwuj to po prostu profilowanie aplikacji sprawdzanie rozmiaru stosu obracanie tej samej aktywności w kółko jeszcze raz. Twoja sterta powinna rosnąć w normalnych parametrach (jest moment, kiedy obiekty, które muszą być zbierane śmieci, żyją w tym samym czasie z nowymi obiektami), ale gdy GC uruchomi Twój przydział pamięci RAM powinien spaść do tego samego rozmiaru, który przydzielono na początku.

Więc jak będę musiał coś polecić to będzie następne:

Activity managing API Calls and Flows (with RoboSpice, letting de UI rotate) Proste ekrany wewnątrz fragmentów przy użyciu retainInstance w true. This let aby przekazać swoje DTOs bezpośrednio do swoich fragmentów, a trzeba zarządzać tylko stan na najwyższym poziomie aktywności.

 4
Author: noni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-19 18:20:31

Jeśli obsługa asyncTask jest twoim głównym zmartwieniem, tzn. nie chcesz pobierać danych za każdym razem, gdy zmieniana jest orientacja, możesz spróbować w ten sposób --

(1) Zainicjalizuj dowolną wartość przed utworzeniem w ten sposób ..

Boolean android_hacker = false;

(2) Teraz po zakończeniu pobierania danych z klasy AsyncTask ustaw tę wartość na true

android_hacker = true;

Tutaj zachowaj wszystkie dane wykorzystujące model i klasę adaptera tablicy

(3) Teraz każdorazowo zmieniana jest orientacja, następnie zaznacz jak this

if( android_hacker = true ){

// Use your saved instance ..

}else{

// Download data as it is yet not downloaded ..

}
Mam nadzieję, że to pomoże ..
 3
Author: AndroidHacker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-18 06:19:59

Istnieje wiele sposobów, które możesz wypróbować obok funkcji AsyncTask. A jeśli spróbujesz znaleźć najlepszą praktykę, AsyncTask nie jest dobrym rozwiązaniem. Ta odpowiedź wyjaśnia, dlaczego nie powinieneś używać AsyncTask. I zalecają użycie lepszego sposobu, który poradzi sobie z długimi zadaniami, RoboSpice .
korzystałem już z tej biblioteki i myślę, że warto spróbować: szanować cykle życia aktywności( zmiana orientacji), brak wycieków pamięci, obsługuje wielowątkowość, buforuje wyniki... Może podłączyć i odłącz zadanie long request za pomocą pamięci podręcznej(ale nie może działać dobrze dla żądania non-cache).

Ale polecam dobry sposób pochodzi z Google: IntentService i BroadcastReceiver. Będziesz zarejestrowany i niezarejestrowany podczas zmiany orientacji, aby otrzymać wynik danych. Wszystkie zadania w tle będą działać w IntentService i powiadamiać o tym, co chcesz zrobić przez BroadcastReceiver. Istnieje wiele przykładów, które można spróbować. Coś w tym stylu.: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/

Update :

Cześć R4j, chodzi o to, że moja aplikacja jest cicha. I muszę zrobić liczba równoległych połączeń sieciowych. Twoje podejście do IntentService jest dobry, ale nie nadaje się do złożonych scenariuszy

Nie sądzę, żeby to był problem. Możesz zrobić wszystko z IntentService, nawet skomplikowane zadania. Jeśli chcesz równoległych zadań, możesz może rozważać usługę z wielowątkowością i komunikować się z aktywnością przez intencję. Wysyłanie intencji między usługą a aktywnością jest bezpieczne i elastyczne, to jest sposób Android.
i jeśli chcesz buforować (przez pobranie pliku, strumień, przez bazę danych.. To najlepszy wybór dla Ciebie]}
 2
Author: R4j,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:32:14

Możesz spróbować z następującymi podejściami:

1) Jeśli aplikacja nie jawnie wymaga żadnych zmian orientacji, po prostu wyłącz zmiany orientacji na początku uruchamiania aplikacji, dzięki czemu unikniesz awarii lub powiązanych problemów związanych ze zmianami orientacji.

Można to zrobić za pomocą następującego wiersza w najbardziej wysuniętym układzie pliku XML układu:

  android:orientation="vertical"

(do ustawiania orientacji pionowej)

2) możesz ustawić lub zachowaj poprzednie wartości orientacyjne na początku wykonywania wątku przy użyciu Asynctask, w następujący sposób (tylko przykład składni):

  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

I

  getResources().getConfiguration().orientation
 -3
Author: SoulRayder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-11 09:37:11