2011-05-09 112 views
38

我在某个活动中遇到了一个监听器问题。检查活动是否有效

问题是这个监听器包含一个alert.show();这可以在我们尝试推送新活动(然后发出异常)后调用。

例如:我在活动A中收听来自其他手机的信号。我按回去尝试运行新的活动B,但由于alert.show()的监听器,程序崩溃。

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

我可以在A的监听器中检查此活动是否处于活动状态,然后根据此值显示警报吗?

+0

您是否在应用程序中使用了选项卡? – 2011-05-09 07:59:00

+0

不可以,每个活动都有自己的xml文件 – Vincent 2011-05-09 08:05:05

回答

55

可能有更简单的方法我想不出来,但一种方法是自己实现它。在onResume()上,您将成员变量mIsRunning设置为true,并将onPause()设置为false。使用这个布尔值,你应该知道不要在你的回调中调用alert.show()

+0

如果AsynckTask存在这个问题,您可以检查onPause()方法是否正在运行,如果正在运行,则使用.method cancel(true)取消该任务。 – jcasadellaoller 2015-09-24 11:12:43

+10

为什么没有内置的检查方法? – JohnyTex 2016-02-17 14:15:13

+0

我的问题是不同的,但你的解决方案帮助我。谢谢 – amin 2017-06-18 08:11:16

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() 
    } 

这样,你就会知道,如果有针对性的活动是当前可见的活动,否则您的警报将不显示。

只有当我们在没有完成的两个活动之间导航时,这才会有效。

+5

对于上面的代码工作,你将需要在你的Manifest文件中添加'android.permission.GET_TASKS',否则应用程序崩溃..! – YuDroid 2012-07-20 09:55:53

+0

也许当使用新的apis。我个人不记得加入这个工作。 – Samet 2012-07-20 12:10:04

+0

不适用于选项卡组活动。 – Deepak 2012-09-14 06:40:22

1

我有2个活动& B,我只是想知道活动B从A上运行或不

起初我也跟着“RunningTaskInfo”为解决这个问题,这是行不通的100%。

所以我创建了自己的解决方案,我会发布我的解决方案。使用HashMap和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); 
    } 
} 

}在活动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(); 
} 

在活动A.

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(); 
    } 

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

此解决方案工作正常y在我的情况..我希望它也会对你有帮助。

9

当后台线程完成其工作并尝试显示一个对话框时,活动将通过其销毁而发生。

这个例外是罕见的重现,但当我们做一些异步任务/背景操作,并希望显示一个对话框 活动的上下文,而在我们的活动正在摧毁自己由于某种原因而意味着。

Android操作系统应该处理这种情况,但截至目前它不。

所以在调用对话框之前,请检查活动是否正在运行,而不是在其销毁阶段。

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

首先,'isFinishing'是一种功能,其次,这不是它的用途。它用于检查“活动是暂停还是完全结束”。 – vikki 2013-11-03 17:12:09

+0

@vikki,你是完全正确的它用于检查“活动是简单地暂停还是完全完成”在调用我们的对话之前,我们也检查相同。我们需要检查这一点,因为正如我在回答中指出的那样:“Android操作系统应该处理这种情况,但目前情况并非如此。”好心检查。 !干杯;) – Ali 2013-11-04 09:49:56

+0

我的意思是**在这个问题**中,检查活动是暂停还是结束并不重要,最重要的是活动目前正在运行,'isFinishing()'不会给你任何信息那。 – vikki 2013-11-04 10:28:04

4

完成其网络任务后台后台线程调用主线程上的callback onSuccess()/ onFailure()。如果在那个时候,启动这个后台线程任务的活动不在前台,并且您尝试在onSuccess()/ onFailure()中使用getActivity(),它会给你例外。因此,请在执行任何UI操作之前尝试添加此检查。

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

这实际上是不正确的。 [只有在活动不会被恢复的情况下,才会设置完成](http://stackoverflow.com/a/5227142/1758149) - 如何检测活动是否被触发问题。现在我相信唯一的办法就是接受的答案。 – RyPope 2017-01-12 20:45:49