Przywołując ten post, w którym wymieniono kilka problemów związanych z używaniem singletonów i widziałem kilka przykładów aplikacji na Androida wykorzystujących wzorzec singletonu, zastanawiam się, czy dobrym pomysłem jest używanie singletonów zamiast pojedynczych instancji współdzielonych przez globalny stan aplikacji (podklasowanie android.os. Aplikacja i uzyskiwanie jej poprzez context.getApplication ()).
Jakie zalety / wady miałyby oba mechanizmy?
Szczerze mówiąc, oczekuję tej samej odpowiedzi w tym poście Wzór Singleton z aplikacją internetową, To nie jest dobry pomysł! ale dotyczy Androida. Mam rację? Co inaczej różni się w DalvikVM?
EDYCJA: Chciałbym mieć opinie na temat kilku aspektów:
- Synchronizacja
- Wielokrotnego użytku
- Testowanie
źródło
Bardzo polecam singletony. Jeśli masz singletona, który potrzebuje kontekstu:
Wolę singletony od aplikacji, ponieważ pomaga to utrzymać organizację o wiele bardziej uporządkowaną i modułową - zamiast jednego miejsca, w którym musi być utrzymany cały stan globalny w aplikacji, każdy osobny element może zająć się sobą. Dobry jest także fakt, że singletony leniwie inicjalizują się (na żądanie) zamiast poprowadzić cię ścieżką wykonywania wszystkich inicjalizacji z góry w Application.onCreate ().
Używanie singletonów nie ma w sobie nic złego. Po prostu używaj ich poprawnie, kiedy ma to sens. Struktura systemu Android faktycznie ma ich wiele, aby utrzymywać pamięci podręczne załadowanych zasobów na proces i inne tego typu rzeczy.
Również w przypadku prostych aplikacji wielowątkowość nie staje się problemem dla singletonów, ponieważ z założenia wszystkie standardowe wywołania zwrotne do aplikacji są wysyłane w głównym wątku procesu, więc nie będziesz mieć wielowątkowości, chyba że wprowadzisz to jawnie przez wątki lub pośrednio przez opublikowanie dostawcy treści lub usługi IBinder innym procesom.
Zastanów się, co robisz. :)
źródło
Od: Deweloper> referencje - Aplikacja
źródło
Aplikacja nie jest taka sama jak Singleton. Przyczyny są:
źródło
Miałem ten sam problem: Singleton lub utworzyć podklasę android.os. Aplikacja?
Najpierw próbowałem z Singletonem, ale moja aplikacja w pewnym momencie dzwoni do przeglądarki
i problem polega na tym, że jeśli telefon nie ma wystarczającej ilości pamięci, większość twoich zajęć (nawet Singletonów) jest czyszczona, aby uzyskać trochę pamięci, więc po powrocie z przeglądarki do mojej aplikacji ulegał awarii za każdym razem.
Rozwiązanie: umieść potrzebne dane w podklasie klasy Application.
źródło
Rozważ oba jednocześnie:
Ponadto sugeruję, abyś rozszerzył swój kontekst, aby obejmował nie tylko dostęp do obiektów singletonowych, ale także niektóre funkcje, które muszą być dostępne globalnie, takie jak na przykład: context.logOffUser (), context.readSavedData () itp. Prawdopodobnie zmiana nazwy kontekstu na Fasada miałaby wtedy sens.
źródło
W rzeczywistości są takie same. Jest jedna różnica, którą widzę. Za pomocą klasy Application możesz zainicjować swoje zmienne w Application.onCreate () i zniszczyć je w Application.onTerminate (). W singletonie musisz polegać na inicjowaniu i niszczeniu statyki VM.
źródło
Moje 2 centy:
Zauważyłem, że niektóre pola singletonowe / statyczne zostały zresetowane po zniszczeniu mojej aktywności. Zauważyłem to na niektórych niskiej jakości urządzeniach 2.3.
Mój przypadek był bardzo prosty: mam po prostu prywatny plik „init_done” i statyczną metodę „init”, którą wywołałem z activity.onCreate (). Zauważam, że metoda init ponownie wykonała się po pewnym odtworzeniu działania.
Chociaż nie mogę udowodnić mojej afirmacji, może to dotyczyć KIEDY singleton / klasa została utworzona / wykorzystana jako pierwsza. Kiedy działanie zostaje zniszczone / poddane recyklingowi, wydaje się, że wszystkie klasy, które odnoszą się tylko do tego działania, są również poddawane recyklingowi.
Przeniosłem instancję singletona do podklasy aplikacji. Uzyskuję do nich dostęp z instancji aplikacji. i od tego czasu nie zauważyłem problemu ponownie.
Mam nadzieję, że to może komuś pomóc.
źródło
Z przysłowiowego pyska konia ...
Podczas opracowywania aplikacji może być konieczne globalne udostępnianie danych, kontekstu lub usług w obrębie całej aplikacji. Na przykład, jeśli aplikacja ma dane sesji, takie jak aktualnie zalogowany użytkownik, prawdopodobnie będziesz chciał ujawnić te informacje. W Androidzie wzór rozwiązania tego problemu polega na tym, że instancja android.app.Application jest właścicielem wszystkich danych globalnych, a następnie traktuje instancję aplikacji jako singleton ze statycznymi akcesoriami do różnych danych i usług.
Pisząc aplikację na Androida, masz gwarancję, że masz tylko jedną instancję klasy android.app.Application, więc jest to bezpieczne (i zalecane przez zespół Google Android), aby traktować ją jako singleton. Oznacza to, że można bezpiecznie dodać statyczną metodę getInstance () do implementacji aplikacji. Tak jak:
źródło
Moje działania wywołują finish () (co nie oznacza, że kończy się natychmiast, ale ostatecznie to zrobi) i wywołuje Google Street Viewer. Kiedy debuguję go w Eclipse, moje połączenie z aplikacją zrywa się, gdy wywoływana jest Street Viewer, co rozumiem jako zamknięcie (całej) aplikacji, rzekomo w celu zwolnienia pamięci (ponieważ pojedyncze działanie zakończone nie powinno powodować takiego zachowania) . Niemniej jednak jestem w stanie zapisać stan w pakiecie za pomocą onSaveInstanceState () i przywrócić go w metodzie onCreate () następnej aktywności na stosie. Albo za pomocą statycznego pojedynczego lub subklasowania aplikacji napotykam stan zamknięcia i utraty aplikacji (chyba że zapiszę ją w pakiecie). Tak więc z mojego doświadczenia są takie same w odniesieniu do zachowania państwa. Zauważyłem, że połączenie zostało utracone w Androidzie 4.1.2 i 4.2.2, ale nie w 4.0.7 lub 3.2.4,
źródło