android - studio - Toast creado en un IntentService nunca desaparece
tareas en segundo plano en android (6)
Tengo un IntentService que descarga algunos archivos. El problema es que creo un Toast dentro del IntentService como este
Toast.makeText(getApplicationContext(), "some message", Toast.LENGTH_SHORT).show();
El evento Toast nunca desaparecerá si salgo de la aplicación. La única forma de destruirlo es matar el proceso.
¿Qué estoy haciendo mal?
El problema es que IntentService
no se está ejecutando en el hilo principal de la aplicación. necesita obtener un Handler
para el hilo principal (en onCreate()
) y publicar el Toast
como un Runnable
.
El siguiente código debería hacer el truco:
@Override
public void onCreate() {
super.onCreate();
mHandler = new Handler();
}
@Override
protected void onHandleIntent(Intent intent) {
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MyIntentService.this, "Hello Toast!", Toast.LENGTH_LONG).show();
}
});
}
Esto funciona para mí:
public void ShowToastInIntentService(final String sText) {
final Context MyContext = this;
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast toast1 = Toast.makeText(MyContext, sText, Toast.LENGTH_LONG);
toast1.show();
}
});
};
IntentService creará un hilo para manejar el nuevo intento y lo terminará inmediatamente una vez que la tarea haya terminado. Por lo tanto, el Toast estará fuera de control por un hilo muerto.
Debería ver algunas excepciones en la consola cuando el brindis se muestra en la pantalla.
No deberías crear Toast
s desde un Service
. Deberías usar una Notification
lugar.
Para las personas que se desarrollan en el estudio Xamarin, así es como se hace allí:
Handler handler = new Handler ();
handler.Post (() => {
Toast.MakeText (_Context, "Your text here.", ToastLength.Short).Show ();
});
Para mostrar un brindis cuando el usuario está en una de las actividades de la aplicación.
Solo necesita una referencia de la actividad actual y llámela con este código de ejemplo:
public void showToast(final String msg) {
final Activity a = currentActivity;
if (a != null ) {
a.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(a, msg, Toast.LENGTH_SHORT).show();
}
});
}
}
Hay muchas opciones para obtener la actividad actual, revisa esta pregunta: ¿Cómo obtener el contexto de la actividad actual de primer plano en Android?
Pero utilizo este enfoque:
La aplicación debe tener:
private Activity currentActivity = null;
public Activity getCurrentActivity() {
return currentActivity;
}
public void setCurrentActivity(Activity mCurrentActivity) {
this.currentActivity = mCurrentActivity;
}
Cada actividad debe tener:
@Override
protected void onResume() {
super.onResume();
((MyApplication) getApplication()).setCurrentActivity(this);
}
@Override
protected void onPause() {
super.onPause();
((MyApplication) getApplication()).setCurrentActivity(null);
}