2010-11-17 7 views
102

Pracuję nad dość złożoną aplikacją dla systemu Android, która wymaga dość dużej ilości danych na temat aplikacji (powiedziałbym, że w sumie około 500 KB - jest tak duża dla telefonu komórkowego urządzenie?). Z tego, co mogę powiedzieć, każda zmiana orientacji w aplikacji (w działalności, aby być bardziej precyzyjnym) powoduje całkowite zniszczenie i odtworzenie działania. Na podstawie moich ustaleń, klasa Application nie ma tego samego cyklu życia (tj. Jest zawsze, dla wszystkich celów i celów, zawsze tworzona). Czy ma sens przechowywanie informacji o stanie wewnątrz klasy aplikacji, a następnie odwoływanie się do niej z działania, czy też ogólnie nie jest to "dopuszczalna" metoda ze względu na ograniczenia pamięci na urządzeniach mobilnych? Naprawdę doceniam każdą radę na ten temat. Dzięki!Używanie klasy aplikacji Android do utrwalania danych

+8

Należy pamiętać, że dane w aplikacji można nadal usuwać, jeśli aplikacja jest umieszczana w tle, więc nie jest to rozwiązanie dla danych, które zawsze można odzyskać. Po prostu służy jako metoda polegająca na tym, że nie trzeba tak często odtwarzać drogich przedmiotów. –

+2

Mayra; Nie sądzę, że aplikacja jest "zazwyczaj" usuwana (chociaż, jak ktoś wskazuje później w tym wątku, "może" być). Prawdopodobnie zastosuję pewien rodzaj "hybrydowego" podejścia do korzystania z aplikacji do przechowywania i ładowania danych, ale następnie użyj atrybutu "Android: orientacja" dla działania w pliku manifestu, aby nadpisać normalne zachowanie zburzenie i odbudowanie działalności. Wszystko to, oczywiście, zakłada, że ​​aplikacja może określić "kiedy" jest niszczona, aby dane mogły zostać utrwalone. – Dave

Odpowiedz

129

Nie sądzę, że 500kb będzie tak wielką transakcją.

Opisałeś dokładnie, w jaki sposób rozwiązałem mój problem utraty danych w działaniu. Stworzyłem globalny singleton w klasie Application i mogłem uzyskać do niego dostęp z działań, których użyłem.

Możesz przekazywać dane dookoła w globalnym Singletonie, jeśli będzie ono często używane.

public class YourApplication extends Application 
{  
    public SomeDataClass data = new SomeDataClass(); 
} 

następnie zadzwonić w każdej działalności przez:

YourApplication appState = ((YourApplication)this.getApplication()); 
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here. 

omówię to here in my blog post, w sekcji "Global Singleton."

+1

Niestety ten wpis na blogu nie jest już dostępny pod tym adresem. – mikebabcock

+1

Przenosiłem rzeczy na mojej stronie. Dopóki nie zostanie naprawiony, możesz go znaleźć na archive.org tutaj: https://web.archive.org/web/20130818035631/http://www.bryandenny.com/index.php/2010/05/25/what- I-learned-from-writing-my-first-android-application –

+1

Wiem, że to stary post, ale właśnie natknąłem się na problem, który może rozwiązać, ale ta klasa musi być jakoś potwierdzona w manifeście, nie? nie mogę uzyskać dostępu do klasy, więc czuję, że to jest to, czego mi brakuje ... –

1

Można faktycznie zastąpić funkcję orientacji, aby upewnić się, że aktywność nie zostanie zniszczona i odtworzona. Spójrz na here.

+15

Możesz zrobić wiele rzeczy. To nie znaczy, że są to dobre pomysły. To nie jest dobry pomysł. – Andrew

+0

Testowanie poprzez zmianę orientacji ekranu jest najłatwiejszym sposobem, aby upewnić się, że aplikacja spełnia wymagania Androida. – 18446744073709551615

55

Osoby, które liczą instancję Application, są nieprawidłowe. Na początku może się wydawać, że Application istnieje tak długo, jak cały proces aplikacji istnieje, ale jest to niepoprawne założenie.

System operacyjny może zabić procesy w razie potrzeby. Wszystkie procesy są podzielone na 5 poziomów "killability" specified in the doc.

Na przykład, jeśli aplikacja działa w tle, ponieważ użytkownik odpowiada na przychodzące połączenie, wówczas w zależności od stanu pamięci RAM system operacyjny może (lub nie) zabić proces (niszcząc kod Application przykład w procesie).

Myślę, że lepszym podejściem byłoby persist your data to internal storage file, a następnie przeczytanie go po wznowieniu aktywności.

UPDATE:

Mam wiele negatywnych sprzężeń zwrotnych, więc nadszedł czas, aby dodać wyjaśnień. :) No cóż, początkowo użyłem błędnego założenia, że ​​stan jest naprawdę ważny dla aplikacji. Jeśli jednak twoja aplikacja jest w porządku, czasami traci się stan (może to być kilka obrazów, które będą po prostu ponownie przeczytane/ponownie pobrane), to jest w porządku, aby zachować ją jako członka Application.

+13

Jeśli aplikacja zostanie zabita, to kogo to obchodzi, prawda? Aplikacja zniknęła. Jak rozumiem, Android będzie odzyskiwał procesy zawierające pamięć typu Działania. Jeśli proces zawierający aplikację zostanie zabity (jeśli Android to zrobi?), Jest to w zasadzie podobne do zabicia aplikacji. Użytkownik będzie musiał ponownie uruchomić aplikację i, w tym momencie, kogo to obchodzi? To nowa instancja aplikacji. – Andrew

+13

To była dla nas niespodzianka w produkcji. Uwierz mi, że Android zabija procesy, zależy to tylko od stanu pamięci RAM i innych czynników opisanych w dokumentacji. To był dla nas koszmar, więc podzielę się moim prawdziwym doświadczeniem.Cóż, nie mieliśmy tego na emulatorach, ale w rzeczywistości niektóre urządzenia są "przeciążane" aplikacjami, więc zabicie procesu w tle jest normalną sytuacją. Tak, jeśli użytkownik zdecyduje się pobrać aplikację na pierwszy plan - system operacyjny przywróci swój stos, w tym instancję "Aplikacji", ale nie będą to dane statyczne, na które się liczyć, chyba że je utrzymasz. –

+2

Myślę, że prawdopodobnie zastosuję podejście hybrydowe. Wiedziałem już o oczywistym triku, który ma zastąpić zmianę orientacji (która ma inne zalety). Ponieważ aplikacja jest grą, nie jestem pewien, czy utrwalanie danych pomiędzy uruchomieniami jest wystarczająco "ważne"; chociaż prawdopodobnie nie byłoby to strasznie trudne, ponieważ większość danych może być serializowana (chociaż nie chciałbym serializować i odserializować między każdą zmianą orientacji). Zdecydowanie doceniam wkład. Nie powiedziałbym, że te, które zależą od instancji aplikacji, są "złe". Wiele zależy od aplikacji :). – Dave

6

Jeśli chcesz uzyskać dostęp do "Global Singleton" poza działaniem i nie chcesz przekazać Context przez wszystkie zaangażowane obiekty, aby uzyskać singleton, możesz po prostu zdefiniować statyczny atrybut w swojej klasie aplikacji, który zawiera odniesienie do samego siebie. Po prostu zainicjuj atrybut w metodzie onCreate().

Na przykład:

public class ApplicationController extends Application { 
    private static ApplicationController _appCtrl; 

    public static ApplicationController getAppCtrl() 
    { 
     return _appCtrl; 
    } 
} 

Ponieważ podklasy Application również można uzyskać zasoby, można je uzyskać dostęp jedynie podczas definiowania metody statycznej, które je zwraca, jak:

public static Resources getAppResources() 
{ 
    return _appCtrl.getResources(); 
} 

Ale zachowaj ostrożność podczas omijania odniesień do kontekstu do avoid memory leaks.

+6

Nie pamiętasz, że musisz dodać android: name = ".Kontrola aplikacji" xml przypisać znacznik aplikacji do pliku manifestu, aby klasa mogła utworzyć instancję. – eggie5

+0

W rzeczywistości nie trzeba rozszerzać 'Application', aby to zrobić. Możesz zadeklarować statyczną zmienną składową w ** dowolnej klasie **, aby to zrobić. –

2

Dave, jakie to dane? Jeśli chodzi o ogólne dane odnoszące się do aplikacji jako całości (przykład: dane użytkownika), wtedy rozszerz klasę aplikacji i zapisz ją tam. Jeśli dane dotyczą działania, powinieneś użyć procedur obsługi onSaveInstanceState i onRestoreInstanceState, aby utrzymać dane na rotacji ekranu.

0

Możesz utworzyć klasę aplikacji i zapisać wszystkie dane na tej karcie, aby używać jej w dowolnym miejscu aplikacji.

Powiązane problemy