Wat is het verschil tussen getContext()
, getApplicationContext()
, getBaseContext()
en “this
“?
Hoewel dit een eenvoudige vraag is, kan ik het fundamentele verschil tussen beide niet begrijpen. Geef indien mogelijk enkele eenvoudige voorbeelden.
Antwoord 1, autoriteit 100%
-
View.getContext()
: Retourneert de context waarin de weergave momenteel wordt uitgevoerd. Meestal de huidige actieve activiteit. -
Activity.getApplicationContext()
: geeft de context terug voor de hele applicatie (het proces waarin alle activiteiten worden uitgevoerd)
van). Gebruik dit in plaats van de huidige activiteitscontext als u een
context gebonden aan de levenscyclus van de hele applicatie, niet alleen de
huidige activiteit. -
ContextWrapper.getBaseContext()
: Als je vanuit een andere context toegang nodig hebt tot een Context, gebruik je een ContextWrapper. De
Context waarnaar wordt verwezen van binnenuit dat ContextWrapper toegankelijk is via
getBaseContext().
Antwoord 2, autoriteit 21%
De meeste antwoorden hebben al betrekking op getContext()
en getApplicationContext()
, maar getBaseContext()wordt zelden uitgelegd.
De methode getBaseContext()
is alleen relevant als je een ContextWrapper
hebt.
Android biedt een klasse ContextWrapper
die is gemaakt rond een bestaande Context
met:
ContextWrapper wrapper = new ContextWrapper(context);
Het voordeel van het gebruik van een ContextWrapper
is dat u hiermee “gedrag kunt wijzigen zonder de oorspronkelijke context te wijzigen”. Als u bijvoorbeeld een activiteit heeft met de naam myActivity
, kunt u een View
maken met een ander thema dan myActivity
:
ContextWrapper customTheme = new ContextWrapper(myActivity) {
@Override
public Resources.Theme getTheme() {
return someTheme;
}
}
View myView = new MyView(customTheme);
ContextWrapper
is echt krachtig omdat je hiermee de meeste functies van Context
kunt overschrijven, inclusief code voor toegang tot bronnen (bijv. openFileInput()
, getString()
), interactie met andere componenten (bijv. sendBroadcast()
, registerReceiver()
), verzoeken om machtigingen (bijv. checkCallingOrSelfPermission()
) en het oplossen van bestandssysteemlocaties (bijv. getFilesDir()
). ContextWrapper
is erg handig om apparaat-/versiespecifieke problemen te omzeilen of om eenmalige aanpassingen toe te passen op componenten zoals weergaven die een context vereisen.
De methode getBaseContext()kan worden gebruikt om toegang te krijgen tot de “basis”-context waar de ContextWrapper
omheen loopt. Mogelijk moet u toegang krijgen tot de “basis”-context als u bijvoorbeeld wilt controleren of het een Service
, Activity
of Application
is:
public class CustomToast {
public void makeText(Context context, int resId, int duration) {
while (context instanceof ContextWrapper) {
context = context.baseContext();
}
if (context instanceof Service)) {
throw new RuntimeException("Cannot call this from a service");
}
...
}
}
Of als u de “uitgepakte” versie van een methode moet aanroepen:
class MyCustomWrapper extends ContextWrapper {
@Override
public Drawable getWallpaper() {
if (BuildInfo.DEBUG) {
return mDebugBackground;
} else {
return getBaseContext().getWallpaper();
}
}
}
Antwoord 3, autoriteit 7%
De vraag “wat de context is” is een van de moeilijkste vragen in het Android-universum.
Context definieert methoden die toegang krijgen tot systeembronnen, statische middelen van applicaties ophalen, machtigingen controleren, UI-manipulaties uitvoeren en nog veel meer. In wezen is Context
een voorbeeld van een God Object anti-patroon in productie.
Als het gaat om het soort Context
dat we moeten gebruiken, wordt het erg ingewikkeld omdat de hiërarchieboom van Context
-subklassen behalve dat het God-object is, het Liskov-substitutieprincipe schendt brutaal.
Deze blogpost(nu van Wayback Machine) probeert de toepasbaarheid van Context
klassen in verschillende situaties samen te vatten.
Laat me voor de volledigheid de hoofdtabel uit die post kopiëren:
+----------------------------+-------------+----------+---------+-----------------+-------------------+ | | Application | Activity | Service | ContentProvider | BroadcastReceiver | +----------------------------+-------------+----------+---------+-----------------+-------------------+ | Show a Dialog | NO | YES | NO | NO | NO | | Start an Activity | NO¹ | YES | NO¹ | NO¹ | NO¹ | | Layout Inflation | NO² | YES | NO² | NO² | NO² | | Start a Service | YES | YES | YES | YES | YES | | Bind to a Service | YES | YES | YES | YES | NO | | Send a Broadcast | YES | YES | YES | YES | YES | | Register BroadcastReceiver | YES | YES | YES | YES | NO³ | | Load Resource Values | YES | YES | YES | YES | YES | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- Een toepassing KAN hier een activiteit starten, maar er moet een nieuwe taak worden gemaakt. Dit kan passen bij specifieke gebruiksscenario’s, maar kan leiden tot niet-standaard backstack-gedrag in uw toepassing en wordt over het algemeen niet aanbevolen of als een goede praktijk beschouwd.
- Dit is legaal, maar inflatie wordt uitgevoerd met het standaardthema voor het systeem waarop u werkt, niet met wat is gedefinieerd in uw toepassing.
- Toegestaan als de ontvanger null is, die wordt gebruikt voor het verkrijgen van de huidige waarde van een vastgezette uitzending, op Android 4.2 en hoger.
Antwoord 4, autoriteit 7%
getApplicationContext()– Retourneert de context voor alle activiteiten die in de toepassing worden uitgevoerd.
getBaseContext()– Als u toegang wilt tot Context vanuit een andere context binnen de toepassing die u kunt openen.
getContext()– Retourneert de contextweergave alleen de huidige hardloopactiviteit.
Antwoord 5, autoriteit 5%
Context
biedt informatie over de Activity
of Application
voor nieuw gemaakte componenten.
Relevante Context
moet worden verstrekt aan nieuw gemaakte componenten (of het nu gaat om applicatiecontext of activiteitscontext)
Aangezien Activity
een subklasse is van Context
, kan men this
gebruiken om de context van die activiteit te krijgen
Antwoord 6
Van deze docs
Ik heb begrepen dat je het volgende moet gebruiken:
Probeer de context-applicatie te gebruiken in plaats van een context-activiteit
Antwoord 7
getApplicationContext()
dit wordt gebruikt voor applicatieniveau en verwijst naar alle activiteiten.
getContext() en getBaseContext()
is hoogstwaarschijnlijk hetzelfde. Dit zijn alleen de huidige activiteiten die live zijn.
dit
verwijs altijd naar het huidige klasseobject.
Antwoord 8
dit: huidig klasseobject
getContext(): retourneer context voor huidige live-activiteit
getApplicationContext(): retourneert alle activiteiten die in de applicatie worden uitgevoerd
Antwoord 9
Een Context
is:
- een abstracte klasse waarvan de implementatie wordt verzorgd door het Android-systeem.
- Het geeft toegang tot applicatie-specifieke bronnen en klassen, evenals
oproepen voor operaties op applicatieniveau, zoals het lanceren van activiteiten,
uitzend- en ontvangstintenties, enz.