W różnych fragmentach kodu Androida widziałem:
public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
Nie mogę jednak znaleźć żadnego przyzwoitego wyjaśnienia, które jest lepsze i w jakich okolicznościach należy je zastosować.
Doceniamy wskazówki dotyczące dokumentacji na ten temat oraz wskazówki dotyczące tego, co może się zepsuć, jeśli zostanie wybrany niewłaściwy.
android
android-context
Alnitak
źródło
źródło
Odpowiedzi:
Zgadzam się, że dokumentacja w systemie Android jest niewielka, ale możesz zebrać kilka faktów z różnych źródeł.
Ten post na oficjalnym blogu Google Android dla programistów został napisany głównie po to, aby pomóc w usuwaniu wycieków pamięci, ale zawiera również dobre informacje o kontekstach:
Lektura tego artykułu mówi dalej o różnicy między nimi a tym, kiedy warto rozważyć użycie aplikacji Context (
Activity.getApplicationContext()
) zamiast kontekstu Activitythis
). Zasadniczo kontekst aplikacji jest powiązany z aplikacją i zawsze będzie taki sam przez cały cykl życia aplikacji, ponieważ kontekst kontekstu jest związany z aktywnością i może zostać zniszczony wiele razy, ponieważ aktywność jest niszczona podczas zmian orientacji ekranu i taki.Nie mogłem znaleźć naprawdę nic o tym, kiedy użyć getBaseContext () poza postem od Dianne Hackborn, jednego z inżynierów Google pracujących nad pakietem Android SDK:
To było z postu w grupie dyskusyjnej dla programistów Androida , możesz też rozważyć zadanie pytania, ponieważ garstka osób pracujących na Androidzie monitoruje tę grupę i odpowiada na pytania.
Ogólnie rzecz biorąc, wydaje się, że lepiej jest używać globalnego kontekstu aplikacji, gdy jest to możliwe.
źródło
Don't use getBaseContext()
. Czy ktoś może to wyjaśnić?Oto, co znalazłem na temat użycia
context
:1). W obrębie
Activity
samego siebie należy używaćthis
do nadmuchiwania układów i menu, rejestrowania menu kontekstowych, tworzenia widgetów, inicjowania innych działań, tworzenia nowychIntent
w obrębieActivity
preferencji, tworzenia instancji lub innych metod dostępnych w plikuActivity
.Nadmuchuj układ:
Napompuj menu:
Zarejestruj menu kontekstowe:
Utwórz widżet:
Rozpocznij
Activity
:Ustawienia preferencji:
2). W przypadku klasy obejmującej całą aplikację należy użyć,
getApplicationContext()
ponieważ ten kontekst istnieje przez cały okres użytkowania aplikacji.Pobierz nazwę bieżącego pakietu Androida:
Powiąż klasę dla całej aplikacji:
3). W przypadku obiektów nasłuchujących i innych typów klas Androida (np. ContentObserver) użyj podstawienia kontekstu, takiego jak:
gdzie
this
lubcontext
jest kontekstem klasy (działanie itp.).Activity
podstawienie kontekstu:Podstawienie kontekstu słuchacza:
ContentObserver
podstawienie kontekstu:4). W przypadku
BroadcastReceiver
(w tym wbudowanego / osadzonego odbiornika) użyj własnego kontekstu odbiornika.Zewnętrzne
BroadcastReceiver
:Wbudowany / osadzony
BroadcastReceiver
:5). W przypadku Usług użyj własnego kontekstu usługi.
6). W przypadku Toastów zazwyczaj używaj
getApplicationContext()
, ale tam, gdzie to możliwe, używaj kontekstu przekazanego z działania, usługi itp.Użyj kontekstu aplikacji:
Użyj kontekstu przekazanego ze źródła:
I na koniec, nie używaj
getBaseContext()
zgodnie z zaleceniami programistów platformy Android.AKTUALIZACJA: Dodaj przykłady
Context
użycia.źródło
OuterClass.this
; zobacz komentarze w stackoverflow.com/questions/9605459/…Przeczytałem ten wątek kilka dni temu, zadając sobie to samo pytanie. Moja decyzja po przeczytaniu tego była prosta: zawsze używaj applicationContext.
Jednak napotkałem z tym problem, spędziłem kilka godzin, aby go znaleźć, i kilka sekund, aby go rozwiązać ... (zmiana jednego słowa ...)
Używam LayoutInflater, aby nadmuchać widok zawierający Błystkę.
Oto dwie możliwości:
1)
2)
Następnie robię coś takiego:
Co zauważyłem: jeśli utworzyłeś instancję liniową z aplikacjąContext, to kiedy klikniesz pokrętło w swojej działalności, otrzymasz nieprzechwycony wyjątek, pochodzący z maszyny wirtualnej dalvik (nie z twojego kodu, dlatego dużo wydałem czasu, aby dowiedzieć się, gdzie był mój błąd ...).
Jeśli użyjesz baseContext, to w porządku, otworzy się menu kontekstowe i będziesz mógł wybierać spośród wybranych opcji.
Oto mój wniosek: przypuszczam (nie testowałem tego dalej), że baseContext jest wymagany, gdy mamy do czynienia z kontekstowym menu w twojej aktywności ...
Test został zakończony kodowaniem za pomocą API 8 i przetestowany na HTC Desire, Android 2.3.3.
Mam nadzieję, że mój komentarz do tej pory cię nie nudził i życzę wszystkiego najlepszego. Miłego kodowania ;-)
źródło
Po pierwsze, zgadzam się, że powinniśmy używać kontekstu aplikacji, gdy tylko jest to możliwe. następnie „to” w działaniu. nigdy nie potrzebowałem kontekstu podstawowego.
W moich testach w większości przypadków można je zamieniać. W większości przypadków chcesz uzyskać kontekst, aby uzyskać dostęp do plików, preferencji, bazy danych itp. Dane te są ostatecznie odzwierciedlane jako pliki w prywatnym folderze danych aplikacji (/ data / data /). Bez względu na to, z jakiego kontekstu korzystasz, zostaną zmapowane do tego samego folderu / plików, więc wszystko będzie w porządku.
Tak zaobserwowałem. Może są przypadki, w których powinieneś je rozróżnić.
źródło
W niektórych przypadkach możesz użyć kontekstu działania zamiast kontekstu aplikacji podczas uruchamiania czegoś w wątku. Gdy wątek zakończy wykonywanie i musisz zwrócić wynik z powrotem do działania osoby wywołującej, potrzebujesz tego kontekstu za pomocą procedury obsługi.
źródło
W prostych słowach
getApplicationContext()
jak sugeruje nazwa metody, Twoja aplikacja będzie wiedzieć o szczegółach aplikacji, do których możesz uzyskać dostęp z dowolnego miejsca w aplikacji. Możesz więc skorzystać z tego w powiązaniu usługi, rejestracji transmisji itp.Application context
Będzie działać do momentu zamknięcia aplikacji.getActivity()
lubthis
sprawi, że Twoja aplikacja będzie wiedzieć o bieżącym ekranie, na którym widoczne są również szczegółowe informacje o poziomie aplikacji dostarczone przezapplication context
. Wszystko, co chcesz wiedzieć o bieżącym ekranieWindow
ActionBar
Fragementmanger
, jest dostępne w tym kontekście. Zasadniczo iActivity
rozszerzContext
. Ten kontekst będzie żył, dopóki obecny składnik (działanie) nie będzie żywyźródło
Co to jest kontekst? Osobiście lubię myśleć o kontekście jako o stanie twojej aplikacji w dowolnym momencie. Kontekst aplikacji reprezentuje globalną lub podstawową konfigurację aplikacji, a Działanie lub Usługa może się na niej opierać i reprezentuje instancję konfiguracji aplikacji lub stan przechodni dla niej.
Jeśli spojrzysz na źródło dla android.content.Context, zobaczysz, że Kontekst jest klasą abstrakcyjną, a komentarze do klasy są następujące:
Interfejs do globalnych informacji o środowisku aplikacji. Jest to klasa abstrakcyjna, której implementację zapewnia system Android. Umożliwia dostęp do
application-specific
zasobów i klas, a także wezwania doapplication-level
wykonywania operacji, takich jak uruchamianie działań, nadawanie i przyjmowanie zamiarów itp. Biorę z tego to, że kontekst zapewnia wspólną implementację dostępu do poziomu aplikacji, a także poziomu systemu zasoby. Zasoby na poziomie aplikacji mogą uzyskiwać dostęp do takich zasobów jak zasoby[getResources()]
lub zasoby String, a zasoby na[getAssets()]
poziomie systemu to wszystko, do czego masz dostępContext.getSystemService().
W rzeczywistości spójrz na komentarze dotyczące metod i wydają się one potwierdzać to pojęcie:
getSystemService()
: Zwróć uchwyt dosystem-level
usługi według nazwy. Klasa zwracanego obiektu różni się w zależności od żądanej nazwy.getResources()
: Zwraca instancję zasobów dla pakietu aplikacji.getAssets()
: Zwraca instancję zasobów dla pakietu aplikacji. Warto zauważyć, że w klasie abstrakcyjnej Context wszystkie powyższe metody są abstrakcyjne! Tylko jedna instancja getSystemService (Class) ma implementację, która wywołuje metodę abstrakcyjną. Oznacza to, że implementacja dla nich powinna być zapewniona głównie przez klasy implementacyjne, które obejmują:Patrząc na dokumentację API, hierarchia klas wygląda następująco:
Kontekst
| - ContextWrapper
| - - Zastosowanie
| - - ContextThemeWrapper
| - - - - Aktywność
| - - Usługa
| - - - IntentService
Ponieważ wiemy, że
Context
sam w sobie nie daje wglądu, schodzimy w dół drzewa i przyglądamy się temuContextWrapper
i zdajemy sobie sprawę, że tam też nie ma wiele. Ponieważ aplikacja się rozszerzaContextWrapper
, nie ma tam wiele do zobaczenia, ponieważ nie zastępuje ona implementacji dostarczonej przezContextWrapper
. Oznacza to, że implementacja kontekstu jest zapewniana przez system operacyjny i jest ukryta przedAPI
. Możesz rzucić okiem na konkretną implementację Context, patrząc na źródło klasy ContextImpl.źródło
Użyłem tylko tego i
getBaseContext
podczas opiekania zonClick
(bardzo zielonego nooba na Javę i Androida). Używam tego, gdy mój pilot jest bezpośrednio w działaniu i muszę go użyćgetBaseContext
w anonimowym wewnętrznym pilocie. Zgaduję, że to w zasadzie podstępgetBaseContext
, może przywraca kontekst działania, w którym ukrywa się klasa wewnętrzna.źródło
MyActivity.this
. Używanie opisanego kontekstu podstawowego prawdopodobnie nie spowoduje problemów, ale jest złe.