getApplication () vs. getApplicationContext()

Nie mogłem znaleźć satysfakcjonującej odpowiedzi na to pytanie, więc zaczynamy: o co chodzi z Activity/Service.getApplication() i Context.getApplicationContext()?

W naszej aplikacji obie zwracają ten sam obiekt. Jednak w ActivityTestCase wyśmiewanie aplikacji spowoduje, że getApplication() powróci z makietą, ale getApplicationContext nadal zwróci inną instancję kontekstową (wstrzykniętą przez Androida). Czy to robak? Czy to celowo?

Nie rozumiem różnicy. Czy są przypadki poza zestawem testowym, w których oba połączenia może wrócić z różnymi przedmiotami? Kiedy i dlaczego? Co więcej, Dlaczego getApplication jest zdefiniowane na Activity i Service, a nie na Context? Czy nie powinna być zawsze dostępna ważna instancja aplikacji z gdziekolwiek ?
Author: Flow, 2011-02-16

4 answers

Bardzo ciekawe pytanie. Myślę, że jest to głównie znaczenie semantyczne, i może być również ze względów historycznych.

Chociaż w obecnych implementacjach usług i aktywności Androida, getApplication() i getApplicationContext() zwracają ten sam obiekt, nie ma gwarancji, że zawsze tak będzie (na przykład w konkretnej implementacji dostawcy).

Więc jeśli chcesz, aby Klasa aplikacji została zarejestrowana w manifeście, powinieneś nigdy zadzwonić getApplicationContext() i wrzucić ją do swojego aplikacji, ponieważ może to nie być instancja aplikacji (czego oczywiście doświadczyłeś z frameworkiem testowym).

Dlaczego getApplicationContext() istnieje w ogóle ?

getApplication() jest dostępna tylko w klasie Activity I klasie Service, podczas gdy getApplicationContext() jest zadeklarowana w klasie Context.

To w rzeczywistości oznacza jedno : pisząc kod w odbiorniku, który nie jest kontekstem, ale ma kontekst w swojej metodzie onReceive, możesz wywołać tylko getApplicationContext(). Które również oznacza, że nie masz gwarancji, aby mieć dostęp do aplikacji w BroadcastReceiver.

Patrząc na kod Androida, widzisz, że po dołączeniu aktywność otrzymuje kontekst bazowy i aplikację, a to są różne parametry. getApplicationContext() delegatów to wezwanie do baseContext.getApplicationContext().

Jeszcze jedno: dokumentacja mówi, że w większości przypadków nie powinno być potrzeby podklasowania aplikacji:

Zazwyczaj nie ma potrzeby podklasowania Application. W większości sytuacja, statyczne singletony mogą zapewnić tę samą funkcjonalność w bardziej modułowym sposób. Jeśli twój singleton potrzebuje globalnego kontekstu (np. aby zarejestrować odbiorników nadawczych), funkcja jej pobierania może być Context który wewnętrznie używa Context.getApplicationContext() gdy pierwsze zbudowanie singletonu.

Wiem, że to nie jest dokładna i precyzyjna odpowiedź, ale czy to odpowiada na twoje pytanie?
 343
Author: Pierre-Yves Ricau,
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
2018-06-08 18:46:40

Porównaj getApplication() oraz getApplicationContext().

getApplication zwraca Application obiekt, który pozwoli Ci zarządzać globalnym stanem aplikacji i reagować na niektóre sytuacje urządzenia, takie jak onLowMemory() oraz onConfigurationChanged().

getApplicationContext zwraca globalny kontekst aplikacji-różnica w porównaniu z innymi kontekstami polega na tym, że na przykład kontekst aktywności może zostać zniszczony (lub w inny sposób niedostępny) przez system Android po zakończeniu aktywności. Wniosek kontekst pozostaje dostępny przez cały czas istnienia obiektu aplikacji (który nie jest powiązany z konkretnym Activity), więc możesz go używać do takich rzeczy, jak powiadomienia , które wymagają kontekstu, który będzie dostępny przez dłuższy czas i niezależny od przejściowych obiektów interfejsu użytkownika.

Myślę, że to zależy od tego, co robi twój kod, czy mogą one być takie same, czy nie - choć w normalnym użyciu, spodziewam się, że będą inne.

 31
Author: RivieraKid,
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
2011-02-16 16:47:53

Wydaje się, że ma to związek z zawijaniem kontekstu. Większość klas pochodzi z Context są rzeczywiście ContextWrapper, które zasadniczo deleguje do innego kontekstu, ewentualnie ze zmianami wprowadzonymi przez wrapper.

Kontekst jest ogólną abstrakcją, która wspiera wyśmiewanie i proxying. Ponieważ wiele kontekstów jest związanych z obiektem o ograniczonej żywotności, takim jak Activity, musi istnieć sposób na uzyskanie długotrwałego kontekstu, do celów takich jak rejestracja na przyszłość powiadomienia. To jest osiągnięte przez Context.getApplicationContext(). Logiczną implementacją jest zwrócenie globalnej Application obiekt, ale nic nie stoi na przeszkodzie, aby implementacja kontekstowa zwróciła wrapper lub proxy z odpowiednim czasem życia.

[[13]}Działalność i usługi są w szczególności związane z Application obiekt. Przydatność tego, jak sądzę, polega na tym, że możesz utworzyć i zarejestrować w manifeście klasę niestandardową pochodzącą z Application i mieć pewność, że Activity.getApplication() lub Service.getApplication() zwróci ten konkretny obiekt danego typu, który możesz rzucić do swojej pochodnej klasy Application i użyć do dowolnego niestandardowego celu.

Innymi słowy, getApplication() ma zagwarantowane zwrócenie Application obiektu, podczas gdy getApplicationContext() może zwrócić zamiast tego proxy.

 28
Author: usethe4ce,
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
2012-11-01 00:26:53

Aby odpowiedzieć na pytanie, getApplication () zwraca obiekt aplikacji, a getApplicationContext () zwraca obiekt kontekstu. Bazując na twoich własnych obserwacjach, zakładam, że kontekst obu jest identyczny(tj. za kulisami Klasa aplikacji wywołuje tę ostatnią funkcję, aby wypełnić część kontekstową klasy bazowej lub ma miejsce jakaś równoważna akcja). Nie powinno mieć znaczenia, którą funkcję wywołujesz, jeśli potrzebujesz tylko kontekstu.

 -12
Author: Lenny Porter,
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
2011-05-04 19:22:35