¿Qué es eso del Contexto?

El contexto es el estado actual de la aplicación o el objeto que instancia la clase Context. Permite acceder a información relativa a la aplicación o el objeto e instanciar elementos de la aplicación. Es como un acceso al conjunto de información de estado de la aplicación.

También es un manejador del sistema que proporciona servicios de resolución de recursos, permitiendo obtener acceso a bases de datos, preferencias, etc…

El objeto Activity hereda de la clase Context, por lo que es un Contexto con acceso al estado de la Aplicación (y por supuesto de la Activity). Es decir, por se un contexto, la Activity y sus elementos podrán acceder a recursos de la aplicación.

Un uso erroneo del Context a utilizar en distintos puntos de la aplicación puede generar una “fuga de memoria”, un “memory leak”, quedándonos sin recursos y pudiendo bloquear la aplicación.

¿Singleton?

The Singleton’s purpose is to control object creation, limiting the number of objects to only one. Since there is only one Singleton instance, any instance fields of a Singleton will occur only once per class, just like static fields. Singletons often control access to resources, such as database connections or sockets. TutoriasPoint

Application Context

Es una clase Singleton del contexto de la Aplicación, por lo que sólo hay una instancia  del Contexto global a toda la aplicación.  Este contexto está vinculado al ciclo de vida de la aplicación.

Puede ser accedido mediante la llamada a getApplicationContext() desde cualquier parte de la aplicación.

Cuando se necesitas un Contexto para un componente de tu aplicación, que estás creando o llamando desde el componente actual (por ejemplo una Activity) y cuyo ciclo de vida estará separado del ciclo de vida del componente actual, necesitarás acceder al contexto de la aplicación, puesto que el elemento actual puede desaparecer antes que el que estás creando, tienen ciclos de vida diferentes.

Por ejemplo, si creas un objeto a nivel aplicación, éste necesitará un contexto, en ese caso usa el contexto de la aplicación. Si pasas el contexto de la Activity, vas a ocasionar una “fuga de memoria”, puesto que el objeto a nivel aplicación mantendrá la referencia al Contexto de la Activity, por lo que cuando la Activity se tenga que destruir, será imposible, pues hay referencias hacia ella, manteniéndose en memoria recursos innecesarios. Si vuelves a abrir la Actividad que instancia el objeto global se creará una nueva Activity que será nuevamente vinculada y que tampoco será liberada de memoria por el Garbage Collector, consumiendo más y más memoria conforme se use la aplicación.

Sólo usarás get ApplicationContext() cuando sepas que vas a necesitar un Context para algo que va a vivir más que cualquier otro Context que tengas a disposición para usar.

Activity Context

Este contexto está disponible en el Activity, pues hereda de Context. Está vinculado al ciclo de vida de la activity. Mientras estés en el ámbito de la Activity podrás pasar este contexto, o cuando necesitas concretamente el contexto vinculado al ciclo de vida actual.

Si estás creando un Toast para ser mostrado desde un Activity en curso, usarás el contexto del Activity. En general cuando estás creando un objeto cuyo ciclo de vida está ligado a la activity, es decir, cuando la Activity muera, el objeto también deberá morir.

Aunque estés en un Activity y puedas acceder al Contexto de la Aplicación, este no contiene algunas cosas relativas al GUI (Graphic User Interface) por lo que puede fallar. Usa el contexto de la Activity para cuestiones de interface de usuario

ContentProvider

Cuando usamos getContext() en un ContentProvider estamos accediendo al contexto de la aplicación, al Application Context.