android - studio - ¿Cuál es la diferencia entre los diversos métodos para obtener un contexto?
para que sirve context en android studio (7)
En varios bits de código de Android que he visto:
public class MyActivity extends Activity {
public void method() {
mContext = this; // since Activity extends Context
mContext = getApplicationContext();
mContext = getBaseContext();
}
}
Sin embargo, no puedo encontrar ninguna explicación decente de cuál es preferible y en qué circunstancias se debe utilizar.
Se agradecerán los indicadores a la documentación sobre esto, y la orientación sobre lo que podría romperse si se elige el incorrecto.
En algunos casos, puede usar el contexto de la actividad sobre el contexto de la aplicación cuando ejecute algo en un hilo. Cuando el subproceso completa la ejecución y necesita devolver el resultado a la actividad de la persona que llama, necesita ese contexto con un controlador.
((YourActivity) context).yourCallbackMethod(yourResultFromThread, ...);
En palabras simples
getApplicationContext()
como sugiere el nombre del método, hará que su aplicación tenga conocimiento de los detalles amplios de la aplicación, a los que puede acceder desde cualquier parte de la aplicación. Por lo tanto, puede hacer uso de esto en enlace de servicio, registro de transmisión, etc. El Application context
estará vivo hasta que la aplicación salga.
getActivity()
o this
hará que su aplicación esté al tanto de la pantalla actual, que también se puede ver en los detalles del nivel de la aplicación que proporciona el application context
. Por lo tanto, lo que quieras saber sobre la pantalla actual, como Window
ActionBar
Fragementmanger
está disponible en este contexto. Básicamente y la Activity
extienden el Context
. Este contexto seguirá vivo hasta que el componente (actividad) actual esté vivo.
Esto es lo que he encontrado con respecto al uso del context
:
1). Dentro de una Activity
sí, use this
para inflar diseños y menús, registrar menús contextuales, crear widgets, iniciar otras actividades, crear nuevas Intent
dentro de una Activity
, crear instancias de preferencias u otros métodos disponibles en una Activity
.
Diseño inflado:
View mView = this.getLayoutInflater().inflate(R.layout.myLayout, myViewGroup);
Inflar menú:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
this.getMenuInflater().inflate(R.menu.mymenu, menu);
return true;
}
Menú contextual de registro:
this.registerForContextMenu(myView);
Widget de instanciación:
TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
Iniciar una Activity
:
Intent mIntent = new Intent(this, MyActivity.class);
this.startActivity(mIntent);
Preferencia de preferencias:
SharedPreferences mSharedPreferences = this.getPreferenceManager().getSharedPreferences();
2). Para la clase de toda la aplicación, use getApplicationContext()
ya que este contexto existe para la vida útil de la aplicación.
Recupera el nombre del paquete actual de Android:
public class MyApplication extends Application {
public static String getPackageName() {
String packageName = null;
try {
PackageInfo mPackageInfo = getApplicationContext().getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), 0);
packageName = mPackageInfo.packageName;
} catch (NameNotFoundException e) {
// Log error here.
}
return packageName;
}
}
Enlazar una clase de toda la aplicación:
Intent mIntent = new Intent(this, MyPersistent.class);
MyServiceConnection mServiceConnection = new MyServiceConnection();
if (mServiceConnection != null) {
getApplicationContext().bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
3). Para los oyentes y otro tipo de clases de Android (por ejemplo, ContentObserver), use una sustitución de contexto como:
mContext = this; // Example 1
mContext = context; // Example 2
donde this
o context
es el contexto de una clase (Actividad, etc.).
Sustitución de contexto de Activity
:
public class MyActivity extends Activity {
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
}
}
Sustitución del contexto del oyente:
public class MyLocationListener implements LocationListener {
private Context mContext;
public MyLocationListener(Context context) {
mContext = context;
}
}
ContentObserver
contexto ContentObserver
:
public class MyContentObserver extends ContentObserver {
private Context mContext;
public MyContentObserver(Handler handler, Context context) {
super(handler);
mContext = context;
}
}
4). Para BroadcastReceiver
(incluido el receptor integrado / en línea), use el propio contexto del receptor.
BroadcastReceiver
externo:
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
sendReceiverAction(context, true);
}
private static void sendReceiverAction(Context context, boolean state) {
Intent mIntent = new Intent(context.getClass().getName() + "." + context.getString(R.string.receiver_action));
mIntent.putExtra("extra", state);
context.sendBroadcast(mIntent, null);
}
}
}
Emisión en línea / integrada BroadcastReceiver
:
public class MyActivity extends Activity {
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final boolean connected = intent.getBooleanExtra(context.getString(R.string.connected), false);
if (connected) {
// Do something.
}
}
};
}
5). Para Servicios, use el propio contexto del servicio.
public class MyService extends Service {
private BroadcastReceiver mBroadcastReceiver;
@Override
public void onCreate() {
super.onCreate();
registerReceiver();
}
private void registerReceiver() {
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
this.mBroadcastReceiver = new MyBroadcastReceiver();
this.registerReceiver(this.mBroadcastReceiver, mIntentFilter);
}
}
6). Para Toasts, generalmente use getApplicationContext()
, pero cuando sea posible, use el contexto pasado de una Actividad, Servicio, etc.
Utilice el contexto de la aplicación:
Toast mToast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
mToast.show();
Usa el contexto pasado de una fuente:
public static void showLongToast(Context context, String message) {
if (context != null && message != null) {
Toast mToast = Toast.makeText(context, message, Toast.LENGTH_LONG);
mToast.show();
}
}
Y, por último, no use getBaseContext()
como lo recomiendan los desarrolladores de aplicaciones de Android.
ACTUALIZACIÓN: Agregar ejemplos de uso de Context
.
Estoy de acuerdo en que la documentación es escasa cuando se trata de Contextos en Android, pero puede juntar algunos datos de varias fuentes.
Esta publicación de blog en el blog oficial de desarrolladores de Google Android se escribió principalmente para ayudar a solucionar las fugas de memoria, pero también proporciona buena información sobre contextos:
En una aplicación normal de Android, normalmente tiene dos tipos de contexto, actividad y aplicación.
Leer el artículo un poco más detalladamente acerca de la diferencia entre los dos y cuándo es posible que desee considerar el uso del contexto de la aplicación ( Activity.getApplicationContext()
) en lugar de usar el contexto de la Actividad). Básicamente, el contexto de la aplicación está asociado con la aplicación y siempre será el mismo durante todo el ciclo de vida de la aplicación, mientras que el contexto de la actividad está asociado con la actividad y podría ser destruido muchas veces, ya que la actividad se destruye durante los cambios de orientación de la pantalla. tal.
Realmente no pude encontrar nada acerca de cuándo usar getBaseContext () aparte de una publicación de Dianne Hackborn, una de los ingenieros de Google que trabaja en el SDK de Android:
No uses getBaseContext (), solo usa el contexto que tienes.
Eso fue a partir de una publicación en el grupo de noticias de desarrolladores de Android , es posible que desee considerar hacer su pregunta allí también, porque un puñado de personas que trabajan en Android monitorean ese grupo de noticias y responden preguntas.
Entonces, en general, parece preferible utilizar el contexto de la aplicación global cuando sea posible.
Leí este hilo hace unos días, haciéndome la misma pregunta. Mi decisión después de leer esto fue simple: siempre use applicationContext.
Sin embargo, encontré un problema con esto, pasé unas horas para encontrarlo y unos segundos para resolverlo ... (cambiando una palabra ...)
Estoy usando un LayoutInflater para inflar una vista que contiene un Spinner.
Así que aquí hay dos posibilidades:
1)
LayoutInflater layoutInflater = LayoutInflater.from(this.getApplicationContext());
2)
LayoutInflater layoutInflater = LayoutInflater.from(this.getBaseContext());
Entonces, estoy haciendo algo como esto:
// managing views part
View view = ContactViewer.mLayoutInflater.inflate(R.layout.aViewContainingASpinner, theParentView, false);
Spinner spinner = (Spinner) view.findViewById(R.id.theSpinnerId);
String[] myStringArray = new String[] {"sweet","love"};
// managing adapter part
// The context used here don''t have any importance -- both work.
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this.getApplicationContext(), myStringArray, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
theParentView.addView(view);
Lo que noté: si creaste una instancia de LinLayout lineal con el applicationContext, entonces cuando hagas clic en el spinner de tu actividad, tendrás una excepción no detectada, proveniente de la máquina virtual dalvik (no de tu código, por eso he gastado mucho de tiempo para encontrar donde fue mi error ...).
Si utiliza el baseContext, está bien, se abrirá el menú contextual y podrá elegir entre sus opciones.
Así que aquí está mi conclusión: Supongo (no lo he probado más) que la baseContext es necesaria cuando se trata de contextMenu en su Actividad ...
La prueba se realizó mediante la codificación con API 8 y se probó en un HTC Desire, Android 2.3.3.
Espero que mi comentario no te haya aburrido hasta ahora, y te deseo lo mejor. Codificación feliz ;-)
Primero, estoy de acuerdo en que deberíamos usar appcontext siempre que sea posible. entonces "esto" en actividad. Nunca he tenido una necesidad de basecontext.
En mis pruebas, en la mayoría de los casos se pueden intercambiar. En la mayoría de los casos, la razón por la que desea obtener una retención de un contexto es para acceder a archivos, preferencias, bases de datos, etc. Estos datos eventualmente se reflejan como archivos en la carpeta de datos privados de su aplicación (/ data / data /). Independientemente del contexto que utilice, se asignarán a la misma carpeta / archivos para que esté bien.
Eso es lo que observé. Tal vez hay casos en que deberías distinguirlos.
Solo he usado esto y getBaseContext
al brindar desde un onClick
(noob muy verde a Java y Android). Uso esto cuando mi clicker está directamente en la actividad y tengo que usar getBaseContext
en un clicker interno anónimo. Supongo que ese es el truco de getBaseContext
, tal vez es devolver el contexto de la actividad en la que se esconde la clase interna.