2011-05-09 23 views
38

Tengo un problema con un oyente en una determinada actividad.Comprobar si la actividad está activa

El problema es que este oyente contiene un alert.show(); que se puede llamar después de que intentamos impulsar una nueva actividad (que luego da una excepción).

e.g .: estoy escuchando en la actividad A una señal de otro teléfono. Presiono hacia atrás y trato de ejecutar una nueva actividad B pero el programa falla debido al listener de alert.show() A.

ERROR/AndroidRuntime(3573): android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running? 

puedo comprobar en el oyente de un si esta actividad está activo y luego mostrar la alerta o no en función de este valor?

+0

¿Está utilizando pestañas en su aplicación? –

+0

No, cada actividad tiene su propio archivo xml – Vincent

Respuesta

55

Puede haber una manera más fácil que no se me ocurre, pero una forma es implementarla usted mismo. En onResume() establece una variable de miembro mIsRunning en true y en onPause() vuelve a falso. Con este booleano, debe saber que no debe llamar al alert.show() en su devolución de llamada.

+0

Si tiene este problema con AsynckTask, puede verificar el método onPause() si se está ejecutando, y si se está ejecutando, cancele la tarea usando .method cancel (true). – jcasadellaoller

+10

¿Por qué no hay un método incorporado para este control? – JohnyTex

+0

Mi problema era diferente, pero su solución ayudó me.Thanks – amin

4

Sí se puede comprobar si la actividad está activo: Refreshing an Activity from service when Active

Además, si su no están haciendo nada cuando su actividad en no está activo, entonces probablemente debería anular el registro del oyente cuando su actividad desactiva.

14
ArrayList<String> runningactivities = new ArrayList<String>(); 

ActivityManager activityManager = (ActivityManager)getBaseContext().getSystemService (Context.ACTIVITY_SERVICE); 

List<RunningTaskInfo> services = activityManager.getRunningTasks(Integer.MAX_VALUE); 

    for (int i1 = 0; i1 < services.size(); i1++) { 
     runningactivities.add(0,services.get(i1).topActivity.toString()); 
    } 

    if(runningactivities.contains("ComponentInfo{com.app/com.app.main.MyActivity}")==true){ 
     Toast.makeText(getBaseContext(),"Activity is in foreground, active",1000).show(); 

     alert.show() 
    } 

De esta manera usted sabrá si la actividad acentuado es la actividad visible actual, de lo contrario su alerta no se mostrará.

Esto solo funcionará cuando naveguemos entre dos actividades sin finalizar.

+5

Para el código de trabajar que se requieren para agregar 'android.permission.GET_TASKS' en su archivo de manifiesto, de lo contrario se bloquea la aplicación ..! – YuDroid

+0

Tal vez al usar nuevas apis. Personalmente no recuerdo haber agregado esto al trabajo. – Samet

+0

No funciona con las actividades del grupo de pestañas. – Deepak

1

que estaba teniendo actividades 2 Un & B, sólo quería saber la actividad B está funcionando o no de A.

Inicialmente i siguieron "RunningTaskInfo" para resolver el problema, No estaba funcionando al 100%.

Así que creé una solución propia, publicaré mi solución. Usando la clase HashMap y AtomicBoolean.

public class ActivityStateTracker { 
final private Map<String, AtomicBoolean> mMap = new HashMap<String, AtomicBoolean>(); 

private static ActivityStateTracker instance = null; 
/** 
* SingletonClass 
* */ 
private ActivityStateTracker() { 

} 

public static ActivityStateTracker getInstance(String activityName, boolean defaultVal) { 

    if(instance == null) { 
     instance = new ActivityStateTracker(); 
    } 
    instance.setDefaultValue(activityName, defaultVal); 
    return instance; 
} 

private void setDefaultValue(String activityName, boolean defaultVal) { 
    mMap.put(activityName, new AtomicBoolean(defaultVal)); 
} 

public boolean isRunning(String activityName) { 
    final AtomicBoolean atomicBool = mMap.get(activityName); 
    return (mMap.get(activityName) == null) ? false : atomicBool.get(); 
} 

public void setChangeState(String activityName, boolean value) { 
    final AtomicBoolean atomicBool = mMap.get(activityName); 

    if(atomicBool == null) { 
     setDefaultValue(activityName, value); 
    } else { 
     atomicBool.set(value); 
     mMap.put(activityName, atomicBool); 
    } 
} 

}

Ahora en la actividad B.

public static final String TAG = "EditScreenPopupActivity"; 

static ActivityStateTracker mActivityState = ActivityStateTracker.getInstance(TAG, false); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mActivityState.setChangeState(TAG, true); 

    requestWindowFeature(Window.FEATURE_NO_TITLE); 

    setContentView(R.layout.activity_traslucent); 

} 

@Override 
protected void onDestroy() { 
    mActivityState.setChangeState(TAG, false); 
    super.onDestroy(); 
} 

Ahora en A. Actividad

public static final String TAG = "ToolTipPopupActivity"; 

static ActivityStateTracker mActivityState = ActivityStateTracker.getInstance(TAG, false); 

    /** Check Edit screen activity is running or not? */ 
    if(mActivityState.isRunning("EditScreenPopupActivity")) { 
     finish(); 
    } 

.............. ........................

Esta solución funciona correctamente y en mi caso ... Espero que te ayude también ...

9

Esto sucede cuando la actividad estará en proceso de destrucción cuando el hilo de fondo termine su trabajo e intente mostrar un cuadro de diálogo.

Esta exepción es rara de reproducir, pero ocurre cuando hacemos alguna operación asincrónica/fondo y queremos mostrar un diálogo con Contexto de la actividad y, mientras tanto, nuestra actividad se está destruyendo por algún motivo.

Android OS debe manejar esta situación, pero por ahora no es así.

así que antes de llamar a sus diálogo simplemente comprobar si la actividad está en marcha y no en su fase de destrucción.

if(!isFinishing()){ 
callDialog(); 
} 
+0

en primer lugar, 'isFinishing' es una función, en segundo lugar, no es para lo que se usa. Se usa para verificar "si la actividad es simplemente pausar o terminar completamente". – vikki

+0

@vikki, tiene toda la razón. Se usa para verificar "si la actividad simplemente se está pausando o terminando por completo". También estamos comprobando lo mismo antes de llamar a nuestro cuadro de diálogo. Necesitamos comprobar esto porque como lo especifiqué en mi respuesta "Android OS debería manejar esta situación, pero a partir de ahora no es así". Cheque bondadoso. !!! Cheers;) – Ali

+0

Lo que quise decir es que ** en esta pregunta **, comprobar si la actividad está en pausa o finalizar no es importante, lo importante es que la actividad se está ejecutando, 'isFinishing()' no le dará ninguna información sobre ese. – vikki

4

hilo de fondo después de terminar sus tareas de red invoca onSuccess de devolución de llamada()/onFailure() en el hilo principal. Y si en ese momento, la actividad que inició esta tarea de subproceso en segundo plano no está en primer plano e intenta utilizar getActivity() en onSuccess()/onFailure(), le dará la excepción. Intente agregar esta comprobación antes de realizar cualquier operación de UI.

if(!((Activity) context).isFinishing()) 
{ 
    //show alert 
} 
+0

Esto es realmente incorrecto. [isFinishing solo se establecerá si la actividad no se va a recuperar] (http://stackoverflow.com/a/5227142/1758149) - la pregunta fue cómo detectar si la actividad está Paused. En este momento, creo que la única forma sería la respuesta aceptada. – RyPope

Cuestiones relacionadas