Differenza tra contesto di attività e contesto di applicazione


233

Questo mi ha lasciato perplesso, lo stavo usando in Android 2.1-r8 SDK:

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

e anche in

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

utilizzando getApplicationContext()crash entrambi ProgressDialoge Toast.... che mi portano a questa domanda:

Quali sono le effettive differenze tra un contesto di attività e un contesto di applicazione, nonostante la condivisione della dicitura "Contesto"?


Questo è quello che ho trovato stackoverflow.com/questions/1561803/... ....
t0mm13b

14
Questo dovrebbe aiutare a chiarire alcune cose: contesto, quale contesto?
toobsco42,

Risposte:


250

Sono entrambe istanze di Context , ma l'istanza dell'applicazione è legata al ciclo di vita dell'applicazione, mentre l'istanza Activity è legata al ciclo di vita di un'attività. Pertanto, hanno accesso a diverse informazioni sull'ambiente dell'applicazione.

Se leggi i documenti su getApplicationContext nota che dovresti usarlo solo se hai bisogno di un contesto il cui ciclo di vita è separato dal contesto corrente. Questo non si applica in nessuno dei tuoi esempi.

Il contesto dell'attività presumibilmente contiene alcune informazioni sull'attività corrente necessarie per completare tali chiamate. Se mostri il messaggio di errore esatto, potresti essere in grado di indicare esattamente ciò di cui ha bisogno.

Ma in generale, usa il contesto dell'attività a meno che tu non abbia una buona ragione per non farlo.


1
Ho ottenuto un 'java.lang.reflect.InvocationTargetException' quando usavo getApplicationContext, abbastanza interessante, quando sono passato a this, non si è bloccato e funzionava come previsto .... quindi se sono entrambe le istanze di Context, perché non si funziona e l'altro fa? Questa informazione sarà di aiuto agli altri, spero ... :) grazie per la pronta risposta ...
t0mm13b

2
Avrei bisogno di vedere l'intera stacktrace delle eccezioni per poter dire qualsiasi cosa. Tuttavia, come ho detto, le istanze di contesto hanno informazioni diverse. Presumibilmente per mostrare una finestra di dialogo o un brindisi sullo schermo sono necessarie informazioni sull'attività che solo l'istanza di attività ha.
Cheryl Simon,

74
Direi di usare il contesto dell'app a meno che tu non abbia buone ragioni non troppo (cioè per dialoghi o brindisi). È abbastanza facile imbattersi in perdite di memoria utilizzando contesti di attività in diverse situazioni, quindi è meglio essere sicuri :) android-developers.blogspot.com/2009/01/…
Dori

10
Dave Smith ha pubblicato un ottimo post nel blog per comprendere l'uso del contesto, vedi qui . Assicurati di leggere anche i commenti!
ChrLipp,

1
Il fatto è che anche Dianna Hackborn consiglia di utilizzare il contesto di attività. stackoverflow.com/questions/5228160/… Ma lei stessa non ne è del tutto sicura.
JacksOnF1re

178

Ho trovato questa tabella super utile per decidere quando utilizzare diversi tipi di contesti:

inserisci qui la descrizione dell'immagine

  1. Un'applicazione PU start iniziare un'attività da qui, ma richiede la creazione di una nuova attività. Questo può adattarsi a casi d'uso specifici, ma può creare comportamenti di back stack non standard nell'applicazione e generalmente non è raccomandato o considerato una buona pratica.
  2. Questo è legale, ma l'inflazione verrà eseguita con il tema predefinito per il sistema su cui si sta eseguendo, non con quello definito nella propria applicazione.
  3. Consentito se il ricevitore è null, utilizzato per ottenere il valore corrente di una trasmissione permanente, su Android 4.2 e versioni successive.

Articolo originale qui .



che ne dici di ottenere le risorse? penso che sia meglio aggiungerlo al tuo tavolo. e puoi accedere alle risorse con il contesto applciation.
Amir Ziarati,

Possiamo iniziare l'attività dal contesto dell'applicazione
Duy Phan,

L'articolo può essere trovato anche qui: wundermanthompsonmobile.com/2013/06/context
Lifes

34

Questo ovviamente è un difetto del design dell'API. In primo luogo, il contesto di attività e il contesto dell'applicazione sono oggetti totalmente diversi, quindi i parametri del metodo in cui viene utilizzato il contesto devono utilizzare ApplicationContexto Activitydirettamente, anziché utilizzare il contesto di classe genitore. In secondo luogo, il documento dovrebbe specificare quale contesto usare o non esplicitamente.


25
Sono completamente d'accordo. Google ha lasciato cadere la palla su questo. È un casino completo.
Søren Boisen,

@ SørenBoisen Android SDK è un casino completo
CommonSenseCode

Sono consapevoli del disordine e sono sicuri che stanno lottando duramente per risolvere il più possibile.
pasignature il

15

La ragione che penso è che ProgressDialogè collegata all'attività che sostiene il fatto ProgressDialogche la finestra di dialogo non può rimanere dopo che l'attività viene distrutta, quindi deve essere passata this(ActivityContext) che viene distrutta anche con l'attività mentre ApplicationContext rimane anche dopo che l'attività viene distrutto.


3

Usa getApplicationContext () se hai bisogno di qualcosa legato a un contesto che a sua volta avrà portata globale.

Se si utilizza l'attività, la nuova istanza di attività avrà un riferimento, che ha un riferimento implicito alla vecchia attività e la vecchia attività non può essere garbage collection.


2

Penso che quando tutto ha bisogno di uno schermo per mostrare (pulsante, finestra di dialogo, layout ...) dobbiamo usare l'attività di contesto, e tutto non ha bisogno di uno schermo per mostrare o elaborare (toast, telelphone di servizio, contatto ...) noi potrebbe usare un contesto applicativo


1

Puoi vedere una differenza tra i due contesti quando avvii l'app direttamente dalla schermata principale rispetto a quando l'app viene avviata da un'altra app tramite l'intento di condivisione.

Ecco un esempio pratico di ciò che "comportamenti non standard dello stack posteriore", menzionato da @CommonSenseCode, significa:

Supponiamo di avere due app che comunicano tra loro, App1 e App2 .

Avvia App2: MainActivity dal programma di avvio. Quindi da MainActivity avvia App2: SecondaryActivity . Lì, usando il contesto di attività o il contesto di applicazione, entrambe le attività vivono nella stessa attività e questo va bene (dato che si utilizzano tutte le modalità di avvio standard e flag di intento). Puoi tornare a MainActivity con una pressione indietro e nelle app recenti hai una sola attività.

Supponi ora di essere in App1 e avviare App2: MainActivity con un intento di condivisione (ACTION_SEND o ACTION_SEND_MULTIPLE). Quindi da lì prova ad avviare App2: SecondaryActivity (sempre con tutte le modalità di avvio standard e flag di intento). Quello che succede è:

  • se avvii App2: SecondaryActivity con il contesto dell'applicazione su Android <10 non puoi avviare tutte le attività nella stessa attività . Ho provato con Android 7 e 8 e SecondaryActivity è sempre avviato in una nuova attività (suppongo sia perché App2: SecondaryActivity è lanciato con il contesto dell'applicazione App2 ma tu provieni da App1 e non hai avviato direttamente l'applicazione App2 Forse sotto il cofano Android lo riconosce e usa FLAG_ACTIVITY_NEW_TASK). Questo può essere positivo o negativo a seconda delle tue esigenze, poiché la mia applicazione è stata negativa.
    Su Android 10 l' app si arresta in modo
    anomalo con il messaggio "La chiamata di startActivity () dall'esterno di un contesto Activity richiede il flag FLAG_ACTIVITY_NEW_TASK. È davvero quello che vuoi?" .
    Quindi per farlo funzionare su Android 10 devi usare FALG_ACTIVITY_NEW_TASK e non puoi eseguire tutte le attività nella stessa attività.
    Come puoi vedere, il comportamento è diverso tra le versioni di Android, strano.

  • se avvii App2: SecondaryActivity con il contesto delle attività tutto va bene e puoi eseguire tutte le attività nella stessa attività con conseguente navigazione nello backstack lineare.

Spero di aver aggiunto alcune informazioni utili

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.