Różnica między kontekstem działania a kontekstem aplikacji


233

To mnie zaskoczyło, korzystałem z tego w zestawie SDK Androida 2.1-r8:

ProgressDialog.show(getApplicationContext(), ....);

a także w

Toast t = Toast.makeText(getApplicationContext(),....);

używanie getApplicationContext()awarii zarówno ProgressDialogi Toast...., które doprowadziły mnie do tego pytania:

Jakie są rzeczywiste różnice między kontekstem działania a kontekstem aplikacji, pomimo wspólnego sformułowania „Kontekst”?


Oto, co znalazłem stackoverflow.com/questions/1561803/ ... ....
t0mm13b

14
To powinno pomóc wyjaśnić niektóre rzeczy: kontekst, jaki kontekst?
toobsco42

Odpowiedzi:


250

Oba są wystąpieniami kontekstu , ale wystąpienie aplikacji jest powiązane z cyklem życia aplikacji, podczas gdy wystąpienie działania jest powiązane z cyklem życia działania. Dzięki temu mają dostęp do różnych informacji o środowisku aplikacji.

Jeśli czytasz dokumenty w getApplicationContext , zauważa, że ​​powinieneś używać tego tylko, jeśli potrzebujesz kontekstu, którego cykl życia jest inny niż bieżący kontekst. Nie dotyczy to żadnego z twoich przykładów.

Kontekst działania prawdopodobnie zawiera pewne informacje o bieżącym działaniu, które są niezbędne do wykonania tych połączeń. Jeśli wyświetli się dokładny komunikat o błędzie, być może uda się wskazać, czego dokładnie potrzebuje.

Ale ogólnie używaj kontekstu aktywności, chyba że masz dobry powód, aby tego nie robić.


1
Dostałem „java.lang.reflect.InvocationTargetException” przy użyciu getApplicationContext, co ciekawe, kiedy zmieniłem na this, nie zawiesił się i nie działał zgodnie z oczekiwaniami ... więc jeśli oba są wystąpieniami kontekstu, dlaczego nie działa i drugi robi? Te informacje będą pomocne dla innych Mam nadzieję ... :) dzięki za szybką odpowiedź ...
t0mm13b

2
Muszę zobaczyć pełny stos śledzenia śledzenia wyjątków, aby móc cokolwiek powiedzieć. Jednak, jak powiedziałem, instancje kontekstowe mają różne informacje. Przypuszczalnie wyświetlenie okna dialogowego lub toastu na ekranie wymaga informacji o działaniu, które ma tylko instancja działania.
Cheryl Simon,

74
Powiedziałbym, że używaj kontekstu aplikacji, chyba że masz też dobry powód (np. Do dialogów lub toastów). Łatwo jest znaleźć wycieki pamięci przy użyciu kontekstów aktywności w różnych sytuacjach, więc najlepiej być bezpiecznym :) android-developers.blogspot.com/2009/01/…
Dori

10
Dave Smith opublikował bardzo dobry wpis na blogu, aby zrozumieć użycie kontekstu, patrz tutaj . Upewnij się, że przeczytałeś również komentarze!
ChrLipp

1
Chodzi o to, że nawet Dianna Hackborn zaleca stosowanie kontekstu aktywności. stackoverflow.com/questions/5228160/… Ale wydaje się, że nie jest do tego całkowicie pewna.
JacksOnF1re

178

Uważam, że ta tabela jest bardzo przydatna przy podejmowaniu decyzji, kiedy używać różnych typów kontekstów:

wprowadź opis zdjęcia tutaj

  1. Aplikacja MOŻE rozpocząć działanie od tego miejsca, ale wymaga utworzenia nowego zadania. Może to pasować do konkretnych przypadków użycia, ale może tworzyć niestandardowe zachowania stosu wstecznego w aplikacji i na ogół nie jest zalecane ani uważane za dobrą praktykę.
  2. Jest to legalne, ale inflacja zostanie wykonana przy użyciu domyślnego motywu dla systemu, na którym działasz, a nie tego, co jest zdefiniowane w twojej aplikacji.
  3. Dozwolone, jeśli odbiornik ma wartość zerową, która służy do uzyskiwania bieżącej wartości lepkiej transmisji na Androidzie 4.2 i nowszych.

Oryginalny artykuł tutaj .



co z pozyskiwaniem zasobów? myślę, że lepiej dodaj to do swojego stołu. i możesz uzyskać dostęp do zasobów w kontekście apliakcji.
Amir Ziarati

Możemy rozpocząć działalność od kontekstu aplikacji
Duy Phan

Artykuł można również znaleźć tutaj: wundermanthompsonmobile.com/2013/06/context
Lifes

34

Jest to oczywiście brak projektu interfejsu API. Po pierwsze, kontekst działania i kontekst aplikacji są całkowicie różnymi obiektami, więc parametry metody, w których stosuje się kontekst, powinny używać bezpośrednio ApplicationContextlub Activityzamiast kontekstu klasy nadrzędnej. Po drugie, dokument powinien określać, którego kontekstu użyć, czy nie jawnie.


25
Zgadzać się w zupełności. Google upuścił piłkę. To kompletny bałagan.
Søren Boisen

@ SørenBoisen android sdk to kompletny bałagan
CommonSenseCode

Są świadomi bałaganu i jestem pewien, że starają się naprawić jak najwięcej.
pasignature

15

Myślę, że jest ProgressDialogto związane z działaniem, które się podpiera, ProgressDialogponieważ okno dialogowe nie może pozostać po zniszczeniu działania, więc musi zostać przekazane this(ActivityContext), które również zostaje zniszczone przez działanie, podczas gdy ApplicationContext pozostaje nawet po tym, jak działanie zostanie pobrane zniszczony.


3

Użyj getApplicationContext (), jeśli potrzebujesz czegoś powiązanego z kontekstem, który sam będzie miał zasięg globalny.

Jeśli użyjesz działania, nowa instancja działania będzie zawierała odwołanie, które zawiera niejawne odwołanie do starego działania, a starego działania nie można wyrzucać.


2

Myślę, że kiedy wszystko potrzebuje ekranu do wyświetlenia (przycisk, okno dialogowe, układ ...) musimy użyć działania kontekstu i wszystko nie potrzebuje ekranu do wyświetlenia lub przetworzenia (toast, telefon służbowy, kontakt ...) mógłby użyć kontekstu aplikacji


1

Możesz zobaczyć różnicę między tymi dwoma kontekstami, gdy uruchamiasz aplikację bezpośrednio z ekranu głównego, a kiedy aplikacja jest uruchamiana z innej aplikacji poprzez zamiar udostępniania.

Oto praktyczny przykład tego, co oznaczają „niestandardowe zachowania stosu wstecznego”, wspomniane przez @CommonSenseCode:

Załóżmy, że masz dwie aplikacje, które komunikują się ze sobą, App1 i App2 .

Uruchom App2: MainActivity z programu uruchamiającego. Następnie z MainActivity uruchom App2: SecondaryActivity . Tam, używając kontekstu działania lub kontekstu aplikacji, obie aktywności działają w tym samym zadaniu i jest to w porządku (biorąc pod uwagę, że używasz wszystkich standardowych trybów uruchamiania i flag intencji). Możesz wrócić do MainActivity, naciskając wstecz, aw najnowszych aplikacjach masz tylko jedno zadanie.

Załóżmy teraz, że jesteś w App1 i uruchom App2: MainActivity z intencją udostępniania (ACTION_SEND lub ACTION_SEND_MULTIPLE). Następnie spróbuj uruchomić App2: SecondaryActivity (zawsze ze wszystkimi standardowymi trybami uruchamiania i flagami intencji). Co się dzieje to:

  • jeśli uruchomisz App2: SecondaryActivity z kontekstem aplikacji na Androidzie <10 , nie możesz uruchomić wszystkich działań w tym samym zadaniu . Próbowałem z Androidem 7 i 8, a SecondaryActivity jest zawsze uruchamiane w nowym zadaniu (chyba dlatego, że App2: SecondaryActivity jest uruchamiany z kontekstem aplikacji App2, ale pochodzisz z App1 i nie uruchomiłeś aplikacji App2 bezpośrednio Być może pod maską android rozpozna to i użyje FLAG_ACTIVITY_NEW_TASK). Może to być dobre lub złe w zależności od potrzeb, ponieważ moja aplikacja była zła.
    Na Androidzie 10 aplikacja ulega awarii z komunikatem
    „Wywołanie startActivity () spoza kontekstu działania wymaga flagi FLAG_ACTIVITY_NEW_TASK. Czy to naprawdę tego chcesz?” .
    Aby więc działało na Androidzie 10, musisz użyć FALG_ACTIVITY_NEW_TASK i nie możesz uruchomić wszystkich działań w tym samym zadaniu.
    Jak widać, zachowanie różni się w zależności od wersji Androida, dziwne.

  • jeśli uruchomisz App2: SecondaryActivity z kontekstem działania, wszystko pójdzie dobrze i możesz uruchomić wszystkie działania w tym samym zadaniu, co spowoduje liniową nawigację po plecach.

Mam nadzieję, że dodałem kilka użytecznych informacji

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.