Diferencia entre getContext (), getApplicationContext (), getBaseContext () y "this"

566

¿Cuál es la diferencia entre getContext(), getApplicationContext(), getBaseContext(), y " this"?

Aunque esta es una pregunta simple, no puedo entender la diferencia básica entre ellos. Por favor, da algunos ejemplos fáciles si es posible.

iCurious
fuente
1
Hay una excelente redacción en la primera respuesta: stackoverflow.com/questions/1026973/…
ky1enamic

Respuestas:

529
  • View.getContext(): Devuelve el contexto en el que la vista se está ejecutando actualmente. Por lo general, la actividad actualmente activa.

  • Activity.getApplicationContext(): Devuelve el contexto de toda la aplicación (el proceso en el que se ejecutan todas las actividades). Use esto en lugar del contexto de Actividad actual si necesita un contexto vinculado al ciclo de vida de toda la aplicación, no solo a la Actividad actual.

  • ContextWrapper.getBaseContext(): Si necesita acceder a un contexto desde otro contexto, utilice ContextWrapper. El contexto al que se hace referencia desde dentro de ese ContextWrapper se accede a través de getBaseContext ().

Alexander Lucas
fuente
59
¿Y qué hay de "esto"?
CooL i3oY
16
+ CooL i3oY lo mismo con getContext
Mikey
13
en realidad estoy confundido de que ¿cuál es la definición adecuada de contexto?
Ravi
11
"this" y getContext () ambos son iguales
KCRaju
43
thisy getContext()no siempre son iguales, por ejemplo, en la clase Actividad, puede usarlo thisporque Activityhereda Contextpero el método getContext()no está en Activityclase. @mikedroid @KCRaju
nandan
92

La mayoría de las respuestas ya cubren getContext()y getApplicationContext()pero getBaseContext () rara vez se explican.

El método getBaseContext()solo es relevante cuando tienes un ContextWrapper. Android proporciona una ContextWrapperclase que se crea alrededor de una existente Contextusando:

ContextWrapper wrapper = new ContextWrapper(context);

El beneficio de usar a ContextWrapperes que te permite "modificar el comportamiento sin cambiar el contexto original". Por ejemplo, si tiene una actividad llamada myActivity, puede crear una Viewcon un tema diferente a myActivity:

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapperes realmente poderoso porque le permite anular la mayoría de las funciones proporcionadas al Contextincluir código para acceder a recursos (por ejemplo openFileInput(), getString()), interactuar con otros componentes (por ejemplo sendBroadcast(), registerReceiver()), solicitar permisos (por ejemplo checkCallingOrSelfPermission()) y resolver ubicaciones del sistema de archivos (por ejemplo getFilesDir()). ContextWrapperes realmente útil para solucionar problemas específicos del dispositivo / versión o para aplicar personalizaciones únicas a componentes como Vistas que requieren un contexto.

El método getBaseContext () se puede utilizar para acceder al contexto "base" que ContextWrapperenvuelve. Es posible que necesite acceder al contexto “base”, si es necesario, por ejemplo, comprobar si se trata de una Service, Activityo Application:

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");
    }
    ...
  }
}

O si necesita llamar a la versión "sin envolver" de un método:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}
Mike Laren
fuente
17
Yo diría que esta es la respuesta más importante después de una aceptada.
0leg
44
Diría que la existencia de ContextWrapperes una de las peores decisiones jamás tomadas por los desarrolladores de Android Framework. Cuando se dieron cuenta de que habían creado una familia completa de Objetos de Dios, en lugar de hacer lo correcto y refactorizar el código hacia la Responsabilidad Única, agregaron un truco feo que permitió cambiar el comportamiento del Contexto al profundizar el árbol de herencia. Mala ingeniería de software en su forma más fea. En cuanto a nosotros, los desarrolladores, en mi humilde opinión, nadie debería usar getBaseContext()o ContextWrapper. Si lo hace, es un gran "olor a código".
Vasiliy
Me gustaría ver el CustomToastcódigo completo . THANKS :)))
Alston
39

getApplicationContext () : devuelve el contexto de todas las actividades que se ejecutan en la aplicación.

getBaseContext () : si desea acceder a Context desde otro contexto dentro de la aplicación, puede acceder.

getContext () : devuelve la vista de contexto solo la actividad actual en ejecución.

Jay Patel
fuente
1
Por favor, incorpore las letras A y B en su definición de contexto dentro de otro contexto, no está claro en ninguna respuesta a qué contexto se accede.
HopefulHelpful
30

La pregunta "cuál es el contexto" es una de las preguntas más difíciles en el universo de Android.

El contexto define métodos que acceden a los recursos del sistema, recuperan los activos estáticos de la aplicación, verifican los permisos, realizan manipulaciones de la interfaz de usuario y muchos más. En esencia, Contextes un ejemplo de Dios Objeto antipatrón en producción.

Cuando se trata de qué tipo de Contextdeberíamos usar, se vuelve muy complicado porque, excepto por ser el Objeto de Dios, el árbol jerárquico de las Contextsubclases viola brutalmente el Principio de sustitución de Liskov.

Esta publicación de blog intenta resumir la Contextaplicabilidad de clases en diferentes situaciones.

Permítanme copiar la tabla principal de esa publicación para completar:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | 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               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. Una aplicación PUEDE iniciar una Actividad desde aquí, pero requiere que se cree una nueva tarea. Esto puede ajustarse a casos de uso específicos, pero puede crear comportamientos de back stack no estándar en su aplicación y generalmente no se recomienda ni se considera una buena práctica.
  2. Esto es legal, pero la inflación se realizará con el tema predeterminado para el sistema en el que está ejecutando, no lo que está definido en su aplicación.
  3. Se permite si el receptor es nulo, que se utiliza para obtener el valor actual de una transmisión fija, en Android 4.2 y superior.

captura de pantalla

Vasiliy
fuente
¡Gran publicación de blog que vinculaste!
lejonl
28

Context proporciona información sobre el Actvity o Applicationlos componentes de nueva creación.

Pertinente ContextSe debe proporcionar a los componentes recién creados (ya sea el contexto de la aplicación o el contexto de la actividad)

Como Activityes una subclase de Context, uno puede usar thispara obtener el contexto de esa actividad

tez
fuente
¿Dónde está tu explicación sobre baseContext?
IgorGanapolsky
1

De estos documentos

Comprendí que deberías usar:

Intente usar la aplicación de contexto en lugar de una actividad de contexto

mehmet
fuente
1

getApplicationContext ()

Esto se utiliza para el nivel de aplicación y se refiere a todas las actividades.

getContext () y getBaseContext ()

Es muy probable que sea lo mismo. Estos se refieren solo a la actividad actual que es en vivo.

esta

es referir el objeto de la clase actual siempre.

Jatin Bansal
fuente
0

A Contextes:

  • Una clase abstracta cuya implementación es proporcionada por el sistema Android.
  • Permite el acceso a recursos y clases específicos de la aplicación, así como llamadas para operaciones a nivel de la aplicación, como actividades de lanzamiento, difusión y recepción de intenciones, etc.
SANKET RAMANI
fuente