Statyczny sposób na uzyskanie „kontekstu” w Androidzie?

970

Czy istnieje sposób na umieszczenie bieżącej Contextinstancji w metodzie statycznej?

Szukam tego, ponieważ nienawidzę zapisywania instancji „Kontekst” za każdym razem, gdy się zmienia.

Andrea Baccega
źródło
57
Niezapisywanie kontekstu to dobry pomysł nie tylko dlatego, że jest niewygodny, ale przede wszystkim dlatego, że może prowadzić do ogromnych wycieków pamięci!
Vikram Bodicherla
12
@VikramBodicherla Tak, ale poniższe odpowiedzi zakładają, że mówimy o kontekście aplikacji. Tak więc wycieki pamięci nie stanowią problemu, ale użytkownik powinien korzystać z tych rozwiązań tylko tam, gdzie jest to właściwy kontekst.
Tom
Jeśli musisz użyć statycznego sposobu uzyskania Context, może być lepszy sposób zaprojektowania kodu.
Anonsage
3
Dokumentacja Androida zaleca przekazywanie kontekstu osobom pobierającym singletony. developer.android.com/reference/android/app/Application.html
Marco Luglio
Jeśli wolisz singletony i kontekst przekazywane za pomocą getInstance () niż kontekst statyczny, spójrz, próbowałem wyjaśnić tutaj moje rozumowanie obsługiwane przez działający kod: stackoverflow.com/a/38967293/4469112
Alessio

Odpowiedzi:

1302

Zrób to:

W pliku manifestu Androida zadeklaruj następujące informacje.

<application android:name="com.xyz.MyApplication">

</application>

Następnie napisz klasę:

public class MyApplication extends Application {

    private static Context context;

    public void onCreate() {
        super.onCreate();
        MyApplication.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MyApplication.context;
    }
}

Teraz zadzwoń wszędzie, MyApplication.getAppContext()aby uzyskać statyczny kontekst aplikacji.

Rohit Ghatol
źródło
81
Czy jest jakaś wada tej metody? To wygląda na oszustwo. (Hack?)
jjnguy,
203
Minusem jest to, że nie ma gwarancji, że antystatyczna funkcja onCreate () zostanie wywołana, zanim jakiś statyczny kod inicjujący spróbuje pobrać obiekt Context. Oznacza to, że Twój kod wywołujący będzie musiał być przygotowany na radzenie sobie z zerowymi wartościami, które w pewnym sensie pokonują cały sens tego pytania.
Melinda Green,
8
Może także… czy powinniśmy zadeklarować tę static contextzmienną jako volatile?
Vladimir Sorokin
14
@Tom To nie jest przypadek statycznego elementu danych będącego początkowo statycznym. W podanym kodzie element statyczny jest inicjowany niestatycznie w funkcji onCreate (). Nawet dane zainicjowane statycznie nie są w tym przypadku wystarczająco dobre, ponieważ nic nie gwarantuje, że statyczna inicjalizacja danej klasy nastąpi przed uzyskaniem dostępu podczas statycznej inicjalizacji innej klasy.
Melinda Green
10
@MelindaGreen Zgodnie z dokumentacją aplikacji, onCreate () jest wywoływany przed utworzeniem jakiejkolwiek działalności, usługi lub odbiorcy (z wyłączeniem dostawców treści). Czy to rozwiązanie nie byłoby bezpieczne, dopóki nie próbujesz uzyskać dostępu do getAppContext () od dostawcy treści?
Magnus W
86

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:

import android.app.Application;
import android.content.Context;

public class App extends Application {

    private static Application sApplication;

    public static Application getApplication() {
        return sApplication;
    }

    public static Context getContext() {
        return getApplication().getApplicationContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sApplication = this;
    }
}

Następnie w swoim AndroidManifest należy podać nazwę swojej klasy w tagu AndroidManifest.xml:

<application 
    ...
    android:name="com.example.App" >
    ...
</application>

Następnie możesz pobrać kontekst aplikacji dowolną metodą statyczną, korzystając z następujących czynności:

public static void someMethod() {
    Context context = App.getContext();
}

OSTRZEŻENIE

Przed dodaniem do projektu czegoś podobnego do powyższego należy rozważyć, co mówi dokumentacja:

Zwykle nie ma potrzeby dzielenia aplikacji. W większości sytuacji statyczne singletony mogą zapewnić tę samą funkcjonalność w bardziej modułowy sposób. Jeśli twój singleton potrzebuje globalnego kontekstu (na przykład w celu zarejestrowania odbiorników rozgłoszeniowych), funkcja do jego odzyskania może otrzymać kontekst, który wewnętrznie używa Context.getApplicationContext () podczas pierwszej budowy singletonu.


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:

public static Application getApplicationUsingReflection() throws Exception {
    return (Application) Class.forName("android.app.ActivityThread")
            .getMethod("currentApplication").invoke(null, (Object[]) null);
}

Jest jeszcze jedna ukryta klasa ( AppGlobals ), która zapewnia sposób na uzyskanie kontekstu aplikacji w sposób statyczny. Pobiera kontekst, ActivityThreadwięc tak naprawdę nie ma różnicy między następującą metodą a tą opisaną powyżej:

public static Application getApplicationUsingReflection() throws Exception {
    return (Application) Class.forName("android.app.AppGlobals")
            .getMethod("getInitialApplication").invoke(null, (Object[]) null);
} 

Miłego kodowania!

Jared Rummler
źródło
56

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

Uwaga: zwykle nie ma potrzeby podklasy aplikacji. W większości sytuacji statyczne singletony mogą zapewnić tę samą funkcjonalność w bardziej modułowy sposób. Jeśli twój singleton potrzebuje globalnego kontekstu (na przykład, aby zarejestrować odbiorniki rozgłoszeniowe), włącz Context.getApplicationContext () jako argument Context podczas wywoływania metody getInstance () twojego singletona.

i wyjaśnione przez Dianne Hackborn

Jedynym powodem, dla którego aplikacja istnieje, jest to, że podczas opracowywania wersji wcześniejszej niż 1.0 jeden z naszych programistów ciągle mnie denerwował, że muszę mieć obiekt aplikacji najwyższego poziomu, z którego mogliby czerpać, aby mogli mieć bardziej „normalny” „dla nich model aplikacji i ostatecznie się poddałem. Na zawsze będę żałować, że się poddałem. :)

Sugeruje również rozwiązanie tego problemu:

Jeśli chcesz uzyskać stan globalny, który można udostępniać w różnych częściach aplikacji, użyj singletonu. [...] A to bardziej naturalnie prowadzi do tego, jak powinieneś zarządzać tymi rzeczami - inicjowanie ich na żądanie.

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:

private static MyHelper instance;
private final Context mContext;    

private MyHelper(@NonNull Context context) {
    mContext = context.getApplicationContext();
}

public static MyHelper getInstance(@NonNull Context context) {
    synchronized(MyHelper.class) {
        if (instance == null) {
            instance = new MyHelper(context);
        }
        return instance;
    }
}

dzwoniący przekaże następnie lokalny kontekst do pomocnika:

Helper.getInstance(myCtx).doSomething();

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

Alessio
źródło
1
@Alessio Czy ta metoda nie powoduje wycieków pamięci
Phillip Kigenyi
2
@codephillip Nie rozumiem o czym mówisz. Singleton odwołuje się do kontekstu aplikacji pobranego z przekazanego działania, a nie do działania hosta. Jest to uzasadnione i nie spowoduje wycieku pamięci. To jest główny punkt bloga, który napisałem. Jeśli naprawdę uważasz, że masz rację, wyślij mi przykładowy kod, w którym mogę odtworzyć wyciek pamięci, o którym mówisz, ponieważ tak nie jest.
Alessio
1
Myślę, że @KigenyiPhillip ma rację, a to nadal oznacza wyciek zasobów. Wyobraź sobie tabelę referencyjną po pierwszym połączeniu z getInstance(ctx). Masz katalog główny instancetypu GC MyHelper, który ma prywatne pole mContexttypu Context, które odwołuje się do kontekstu aplikacji zebranego za pośrednictwem przekazanego kontekstu getInstance(). instancenigdy nie jest ustawiany ani usuwany, więc GC nigdy nie wyłapie kontekstu aplikacji, do którego się odwołuje instance. Nie wyciekają żadne działania, więc jest to tanie IMO.
Mark McKenna,
1
@MarkMcKenna as you state "która ma prywatne pole mContext typu Context, który odwołuje się do kontekstu aplikacji", więc jest dla ciebie jasne, że mContext jest odniesieniem do kontekstu aplikacji, a nie do żadnego kontekstu. W dokumentach getApplicationContext () czytamy: „Kontekst, którego cykl życia jest odrębny od bieżącego kontekstu, który jest związany z czasem życia procesu, a nie bieżącym składnikiem”. Jak może to spowodować wyciek pamięci? Kontekst aplikacji jest przechowywany w GC dopiero po zakończeniu procesu.
Alessio,
1
@Alessio, jeśli akceptujesz, że odwołanie do kontekstu aplikacji nie kwalifikuje się jako wyciek zasobów, możesz to uprościć, publikując stałe odwołanie do thisin Application.onCreate(), co poprawia akceptowaną odpowiedź.
Mark McKenna
49

Nie, nie sądzę, żeby tak było. Niestety utknąłeś dzwoniąc getApplicationContext()z Activityjednej lub innej podklasy Context. Również ta kwestia jest nieco podobne.

Erich Douglass
źródło
8
Właściwy link do artykułu: android-developers.blogspot.co.il/2009/01/…
Tal Weiss
38

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.

try {
    final Class<?> activityThreadClass =
            Class.forName("android.app.ActivityThread");
    final Method method = activityThreadClass.getMethod("currentApplication");
    return (Application) method.invoke(null, (Object[]) null);
} catch (final ClassNotFoundException e) {
    // handle exception
} catch (final NoSuchMethodException e) {
    // handle exception
} catch (final IllegalArgumentException e) {
    // handle exception
} catch (final IllegalAccessException e) {
    // handle exception
} catch (final InvocationTargetException e) {
    // handle exception
}

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.

kennytm
źródło
1
Użyłem powyższej metody KennyTM, ale czasami metoda zwraca wartość null. Czy jest jakaś inna alternatywa? Na przykład, jeśli otrzymamy tutaj zero, możemy pobrać kontekst z innego miejsca. W moim przypadku funkcja onCreate () aplikacji nie jest wywoływana. Ale powyższa metoda jest wywoływana przed nią. Plzzz pomoc
AndroidGuy
Nie zawsze będzie to działać w przypadku, gdy GC wyczyściło wszystkie rzeczy związane z aktywnością.
AlexVPerl
32

To zależy od tego, do czego używasz kontekstu. Mogę wymyślić przynajmniej jedną wadę tej metody:

Jeśli próbujesz utworzyć AlertDialogz AlertDialog.Builder, Applicationkontekst nie będzie działać. Uważam, że potrzebujesz kontekstu dla obecnego Activity...

gulchrider
źródło
6
Zgadza się. Jeśli użyjesz do tego kontekstu aplikacji, możesz zobaczyć swoje okno dialogowe ukryte pod działaniami na pierwszym planie.
Nate
3
+1 przede wszystkim. A możliwym błędem, który się pojawia, jest niemożność uruchomienia działania ComponentInfo {com.samples / com.MyActivity}: android.view.WindowManager $ BadTokenException: Nie można dodać okna - token null nie jest dla aplikacji
Govind
15

Sposób Kotlina :

Oczywisty:

<application android:name="MyApplication">

</application>

MyApplication.kt

class MyApplication: Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    companion object {
        lateinit var instance: MyApplication
            private set
    }
}

Następnie można uzyskać dostęp do nieruchomości za pośrednictwem MyApplication.instance

phnmnn
źródło
11

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)

import android.content.Context;
import android.os.Build;
import roboguice.inject.ContextSingleton;

import javax.inject.Inject;

@ContextSingleton
public class DataManager {
    @Inject
    public DataManager(Context context) {
            Properties properties = new Properties();
            properties.load(context.getResources().getAssets().open("data.properties"));
        } catch (IOException e) {
        }
    }
}
użytkownik605331
źródło
8

W pewnym momencie użyłem tego:

ActivityThread at = ActivityThread.systemMain();
Context context = at.getSystemContext();

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:

java.lang.SecurityException: Dany pakiet dzwoniącego android nie działa w procesie ProcessRecord

ungalcrys
źródło
7

Kotlin

open class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        mInstance = this
    }

    companion object {
        lateinit var mInstance: MyApp
        fun getContext(): Context? {
            return mInstance.applicationContext
        }
    }
}

i uzyskaj jak Kontekst

MyApp.mInstance

lub

MyApp.getContext()
Khemraj
źródło
4

Możesz użyć następujących opcji:

MainActivity.this.getApplicationContext();

MainActivity.java:

...
public class MainActivity ... {
    static MainActivity ma;
...
    public void onCreate(Bundle b) {
         super...
         ma=this;
         ...

Każda inna klasa:

public ...
    public ANY_METHOD... {
         Context c = MainActivity.ma.getApplicationContext();
barwnikk
źródło
3
Działa to tylko wtedy, gdy należysz do klasy wewnętrznej, co nie ma miejsca w OP.
Richard J. Ross III
3
Działałoby to tak długo, jak ANY_METHOD jest wywoływany po utworzeniu MainActivity, ale utrzymywanie statycznych odniesień do działań prawie nieuchronnie powoduje wycieki pamięci (jak już wspomniano w innych odpowiedziach na pytanie OP), więc jeśli naprawdę musisz zachować stałe odwołanie, skorzystaj z aplikacji tylko kontekst.
handtwerk
1
Klasy wewnętrzne są złe. Najgorsze jest to, że wiele osób robi to dla AsyncTasks i tego typu rzeczy, ponieważ wiele samouczków robi to w ten sposób ...
Reinherd
4

Jeśli nie chcesz modyfikować pliku manifestu, możesz ręcznie zapisać kontekst w zmiennej statycznej w początkowej czynności:

public class App {
    private static Context context;

    public static void setContext(Context cntxt) {
        context = cntxt;
    }

    public static Context getContext() {
        return context;
    }
}

I po prostu ustaw kontekst, kiedy rozpocznie się twoja aktywność (lub działania):

// MainActivity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Set Context
    App.setContext(getApplicationContext());

    // Other stuff
}

Uwaga: Podobnie jak wszystkie inne odpowiedzi, jest to potencjalny wyciek pamięci.

Sheharyar
źródło
1
Co dokładnie będzie przeciekać, ponieważ kontekst w tym przypadku jest związany z aplikacją? Jeśli aplikacja umrze, podobnie jak wszystko inne.
TheRealChx101
3

Myślę, że potrzebujesz ciała do getAppContext()metody:

public static Context getAppContext()
   return MyApplication.context; 
Kognos
źródło
3

Według tego źródła można uzyskać własny kontekst, rozszerzając ContextWrapper

public class SomeClass extends ContextWrapper {

    public SomeClass(Context base) {
      super(base);
    }

    public void someMethod() {
        // notice how I can use "this" for Context
        // this works because this class has it's own Context just like an Activity or Service
        startActivity(this, SomeRealActivity.class);

        //would require context too
        File cacheDir = getCacheDir();
    }
}

JavaDoc dla ContextWrapper

Proxy implementacja kontekstu, który po prostu deleguje wszystkie swoje wywołania do innego kontekstu. Można go podklasować, aby zmodyfikować zachowanie bez zmiany oryginalnego kontekstu.

BlueWizard
źródło
1
To jest interesujące. Dobrze jest dowiedzieć się o ContextWrapper. Jeśli jednak musisz przekazać kontekst aplikacji do tego konstruktora, nadal musisz go skądś pobrać.
jk7
2

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.

public class GlobalAppContextSingleton {
    private static GlobalAppContextSingleton mInstance;
    private Context context;

    public static GlobalAppContextSingleton getInstance() {
        if (mInstance == null) mInstance = getSync();
        return mInstance;
    }

    private static synchronized GlobalAppContextSingleton getSync() {
        if (mInstance == null) mInstance = 
                new GlobalAppContextSingleton();
        return mInstance;
    }

    public void initialize(Context context) {
        this.context = context;
    }

    public Context getApplicationContext() {
        return context;
    }
}

następnie zainicjuj go w klasie aplikacji onCreate za pomocą

GlobalAppContextSingleton.getInstance().initialize(this);

używaj go w dowolnym miejscu, dzwoniąc

GlobalAppContextSingleton.getInstance().getApplicationContext()

Jednak nie polecam tego podejścia do niczego poza kontekstem aplikacji. Ponieważ może powodować wycieki pamięci.

Versa
źródło
To nie jest tak, że nazwy klas / metod są ustawione w kamieniu, zachowały długie i (miejmy nadzieję) opisowe pytania i odpowiedzi, skróciły je na własny użytek.
Versa
1

Używam odmiany wzoru Singleton, aby mi w tym pomóc.

import android.app.Activity;
import android.content.Context;

public class ApplicationContextSingleton {
    private static Activity gContext;

    public static void setContext( Activity activity) {
        gContext = activity;
    }

    public static Activity getActivity() {
        return gContext;
    }

    public static Context getContext() {
        return gContext;
    }
}

I wtedy zadzwonić ApplicationContextSingleton.setContext( this );w moim activity.onCreate () i ApplicationContextSingleton.setContext( null );w onDestroy () ;

Bamaco
źródło
Jeśli potrzebujesz tylko kontekstu, możesz wywołać activity.getApplicationContext (); Można to utrzymać na stałym poziomie bez obawy o wycieki.
MinceMan,
2
spowoduje to wycieki pamięci
BlueWizard,
1

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 utrzymuje WeakReference(link do niesamowitego postu na blogu Java na ten temat autorstwa Ethana Nicholasa) do bieżącego Activitykontekstu, który można odzyskać, wywołując:

$.act()

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 VaporActivityjako swojej Activityklasy:

$.act(Activity);

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 :)

Dariusz
źródło
1
Najwyraźniej to właśnie zostało ocenione z góry .. wyjaśnienie byłoby fajne !?
Dariusz
1
Nie głosowałem za tym, ale Javascript nie ma nic wspólnego z tym pytaniem, które wyjaśniałoby wszelkie negatywne opinie! Twoje zdrowie.
Ernani Joppert
Byłoby to dość nonsensowne, biorąc pod uwagę, że jest zainspirowany niektórymi aspektami jQuery, takimi jak płynny interfejs i jego abstrakcje ... są to zasady niezależne od podstawowego języka!
Dariusz
1
Głosujesz za tym, ponieważ został zainspirowany semantyką API frameworka, który nie jest na tej samej platformie ?! Myślę, że nie rozumiecie sensu stosowania zasad niezależnych od platformy .....................................
Dariusz
3
ta odpowiedź jest całkowicie niezwiązana z JavaScript. Przeczytaj odpowiedź, zanim zagłosujesz: /
BlueWizard,
1

Odpowiedź Rohita wydaje się poprawna. Należy jednak pamiętać, że „Natychmiastowe uruchomienie” AndroidStudio zależy od braku static Contextatrybutów w kodzie, o ile wiem.

Payne
źródło
1
Masz rację. I spowoduje to także wycieki pamięci!
user1506104
1

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:

    companion object {
        lateinit var instance: MyApp
    }

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:

object CoreHelper {
    lateinit var contextGetter: () -> Context
}

lub możesz użyć go bezpieczniej, używając typu zerowalnego:

object CoreHelper {
    var contextGetter: (() -> Context)? = null
}

i w swojej klasie aplikacji dodaj ten wiersz:


class MyApp: Application() {

    override fun onCreate() {
        super.onCreate()
        CoreHelper.contextGetter = {
            this
        }
    }
}

i w swoim manifeście zadeklaruj nazwę aplikacji . MyApp


    <application
            android:name=".MyApp"

Jeśli chcesz uzyskać kontekst, po prostu zadzwoń:

CoreHelper.contextGetter()

// or if you use the nullable version
CoreHelper.contextGetter?.invoke()

Mam nadzieję, że to pomoże.

Hayi Nukman
źródło
Klasa obiektu tego pomocnika zostanie zainicjowana i może być wykorzystana w późniejszych etapach? Przepraszam, jestem nowy w kotlin
Dr. aNdRO
tak, dokładnie.
Hayi Nukman,
-1

Spróbuj czegoś takiego

import androidx.appcompat.app.AppCompatActivity;  
import android.content.Context; 
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    private static Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = getApplicationContext();
    }

    public static void getContext(View view){
        Toast.makeText(context, "Got my context!",
                    Toast.LENGTH_LONG).show();    
    }
}
Chandra Shekar
źródło