Czy istnieje sposób na umieszczenie bieżącej Context
instancji w metodzie statycznej?
Szukam tego, ponieważ nienawidzę zapisywania instancji „Kontekst” za każdym razem, gdy się zmienia.
android
android-context
Andrea Baccega
źródło
źródło
Context
, może być lepszy sposób zaprojektowania kodu.Odpowiedzi:
Zrób to:
W pliku manifestu Androida zadeklaruj następujące informacje.
Następnie napisz klasę:
Teraz zadzwoń wszędzie,
MyApplication.getAppContext()
aby uzyskać statyczny kontekst aplikacji.źródło
static context
zmienną jakovolatile
?Większość aplikacji, które chcą w wygodny sposób uzyskać kontekst aplikacji, tworzy własną klasę, która się rozszerza
android.app.Application
.PRZEWODNIK
Możesz to zrobić, najpierw tworząc klasę w swoim projekcie w następujący sposób:
Następnie w swoim AndroidManifest należy podać nazwę swojej klasy w tagu AndroidManifest.xml:
Następnie możesz pobrać kontekst aplikacji dowolną metodą statyczną, korzystając z następujących czynności:
OSTRZEŻENIE
Przed dodaniem do projektu czegoś podobnego do powyższego należy rozważyć, co mówi dokumentacja:
ODBICIE
Istnieje również inny sposób uzyskania kontekstu aplikacji za pomocą odbicia. W Androidzie często spogląda się na refleksję i osobiście uważam, że nie należy tego używać w produkcji.
Aby pobrać kontekst aplikacji, musimy wywołać metodę na ukrytej klasie ( ActivityThread ), która jest dostępna od API 1:
Jest jeszcze jedna ukryta klasa ( AppGlobals ), która zapewnia sposób na uzyskanie kontekstu aplikacji w sposób statyczny. Pobiera kontekst,
ActivityThread
więc tak naprawdę nie ma różnicy między następującą metodą a tą opisaną powyżej:Miłego kodowania!
źródło
Zakładając, że mówimy o uzyskaniu kontekstu aplikacji, zaimplementowałem go zgodnie z sugestią @Rohit Ghatol rozszerzającego aplikację. To, co się wtedy wydarzyło, polega na tym, że nie ma gwarancji, że tak pobrany kontekst zawsze będzie różny od zera. Kiedy jest to potrzebne, zwykle dlatego, że chcesz zainicjować pomocnika lub zdobyć zasób, którego nie możesz opóźnić w czasie; załatwienie sprawy zerowej nie pomoże. Zrozumiałem, że zasadniczo walczę z architekturą Androida, jak stwierdzono w dokumentacji
i wyjaśnione przez Dianne Hackborn
Sugeruje również rozwiązanie tego problemu:
więc pozbyłem się rozszerzania aplikacji i przekazałem kontekst bezpośrednio do getInstance () pomocnika singletona, jednocześnie zapisując odwołanie do kontekstu aplikacji w prywatnym konstruktorze:
dzwoniący przekaże następnie lokalny kontekst do pomocnika:
Tak więc, aby poprawnie odpowiedzieć na to pytanie: istnieją sposoby na statyczny dostęp do kontekstu aplikacji, ale wszystkie powinny być odradzane i powinieneś preferować przekazywanie lokalnego kontekstu do getInstance () singletona.
Dla wszystkich zainteresowanych możesz przeczytać bardziej szczegółową wersję na blogu fwd
źródło
getInstance(ctx)
. Masz katalog głównyinstance
typu GCMyHelper
, który ma prywatne polemContext
typuContext
, które odwołuje się do kontekstu aplikacji zebranego za pośrednictwem przekazanego kontekstugetInstance()
.instance
nigdy nie jest ustawiany ani usuwany, więc GC nigdy nie wyłapie kontekstu aplikacji, do którego się odwołujeinstance
. Nie wyciekają żadne działania, więc jest to tanie IMO.this
inApplication.onCreate()
, co poprawia akceptowaną odpowiedź.Nie, nie sądzę, żeby tak było. Niestety utknąłeś dzwoniąc
getApplicationContext()
zActivity
jednej lub innej podklasyContext
. Również ta kwestia jest nieco podobne.źródło
Oto nieudokumentowany sposób uzyskania aplikacji (która jest kontekstem) z dowolnego miejsca w wątku interfejsu użytkownika. Opiera się na ukrytej metodzie statycznej
ActivityThread.currentApplication()
. Powinien działać przynajmniej na Androidzie 4.x.Zauważ, że ta metoda może zwrócić null, np. Gdy wywołasz metodę poza wątkiem interfejsu użytkownika lub aplikacja nie jest powiązana z wątkiem.
Nadal lepiej jest użyć rozwiązania @RohitGhatol , jeśli możesz zmienić kod aplikacji.
źródło
To zależy od tego, do czego używasz kontekstu. Mogę wymyślić przynajmniej jedną wadę tej metody:
Jeśli próbujesz utworzyć
AlertDialog
zAlertDialog.Builder
,Application
kontekst nie będzie działać. Uważam, że potrzebujesz kontekstu dla obecnegoActivity
...źródło
Sposób Kotlina :
Oczywisty:
MyApplication.kt
Następnie można uzyskać dostęp do nieruchomości za pośrednictwem
MyApplication.instance
źródło
Jeśli jesteś otwarty na używanie RoboGuice , możesz wprowadzić kontekst do dowolnej klasy. Oto mała próbka tego, jak to zrobić za pomocą RoboGuice 2.0 (beta 4 w momencie pisania tego tekstu)
źródło
W pewnym momencie użyłem tego:
To jest prawidłowy kontekst, z którego korzystałem i korzystałem z usług systemowych.
Ale użyłem go tylko w modyfikacjach szkieletu / bazy i nie wypróbowałem go w aplikacjach na Androida.
Ostrzeżenie , że trzeba wiedzieć: Przy rejestracji dla odbiorników z tym kontekście, to nie będzie działać, a otrzymasz:
źródło
Kotlin
i uzyskaj jak Kontekst
lub
źródło
Możesz użyć następujących opcji:
MainActivity.java:
Każda inna klasa:
źródło
Jeśli nie chcesz modyfikować pliku manifestu, możesz ręcznie zapisać kontekst w zmiennej statycznej w początkowej czynności:
I po prostu ustaw kontekst, kiedy rozpocznie się twoja aktywność (lub działania):
Uwaga: Podobnie jak wszystkie inne odpowiedzi, jest to potencjalny wyciek pamięci.
źródło
Myślę, że potrzebujesz ciała do
getAppContext()
metody:źródło
Według tego źródła można uzyskać własny kontekst, rozszerzając ContextWrapper
JavaDoc dla ContextWrapper
źródło
Jeśli z jakiegoś powodu chcesz kontekst aplikacji w dowolnej klasie, nie tylko rozszerzającej aplikację / działalność, może dla niektórych klas fabrycznych lub pomocniczych. Możesz dodać następujący singleton do swojej aplikacji.
następnie zainicjuj go w klasie aplikacji onCreate za pomocą
używaj go w dowolnym miejscu, dzwoniąc
Jednak nie polecam tego podejścia do niczego poza kontekstem aplikacji. Ponieważ może powodować wycieki pamięci.
źródło
Używam odmiany wzoru Singleton, aby mi w tym pomóc.
I wtedy zadzwonić
ApplicationContextSingleton.setContext( this );
w moim activity.onCreate () iApplicationContextSingleton.setContext( null );
w onDestroy () ;źródło
Właśnie wydałem inspirowaną przez jQuery platformę dla systemu Android o nazwie Vapor API która ma na celu uproszczenie tworzenia aplikacji.
Centralna
$
klasa elewacji utrzymujeWeakReference
(link do niesamowitego postu na blogu Java na ten temat autorstwa Ethana Nicholasa) do bieżącegoActivity
kontekstu, który można odzyskać, wywołując:ZA
WeakReference
zachowuje odwołanie, nie zapobiegając odzyskiwaniu oryginalnego obiektu przez śmietnik, więc nie powinieneś mieć problemu z wyciekami pamięci.Minusem jest oczywiście to, że ryzykujesz
$.act()
zerową wartością. Jeszcze nie spotkałem się z tym scenariuszem, więc warto wspomnieć, że jest to tylko minimalne ryzyko.Możesz także ustawić kontekst ręcznie, jeśli nie używasz
VaporActivity
jako swojejActivity
klasy:Ponadto, większość frameworku API Vapor korzysta z tego przechowywanego kontekstu, co może oznaczać, że nie musisz go wcale przechowywać, jeśli zdecydujesz się użyć frameworka. Sprawdź stronę, aby uzyskać więcej informacji i próbek.
Mam nadzieję że to pomogło :)
źródło
Odpowiedź Rohita wydaje się poprawna. Należy jednak pamiętać, że „Natychmiastowe uruchomienie” AndroidStudio zależy od braku
static Context
atrybutów w kodzie, o ile wiem.źródło
w Kotlin, umieszczenie kontekstu / kontekstu aplikacji w obiekcie towarzyszącym nadal generuje ostrzeżenie
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
lub jeśli używasz czegoś takiego:
Po prostu oszukujemy strzępy, aby nie wykryły przecieku pamięci, instancja aplikacji nadal może powodować wyciek pamięci, ponieważ klasa aplikacji i jej potomek są kontekstem.
Alternatywnie możesz użyć interfejsu funkcjonalnego lub właściwości funkcjonalnych, aby uzyskać kontekst aplikacji.
Wystarczy utworzyć klasę obiektu:
lub możesz użyć go bezpieczniej, używając typu zerowalnego:
i w swojej klasie aplikacji dodaj ten wiersz:
i w swoim manifeście zadeklaruj nazwę aplikacji
. MyApp
Jeśli chcesz uzyskać kontekst, po prostu zadzwoń:
Mam nadzieję, że to pomoże.
źródło
Spróbuj czegoś takiego
źródło