检查活动是否有效

时间:2011-05-09 07:52:51

标签: android

我在某个活动中遇到了监听器的问题。

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

例如:我正在通过活动A收听来自另一部手机的信号。我按回并尝试运行一个新的活动B,但程序崩溃是因为alert.show()A的监听器。

ERROR/AndroidRuntime(3573): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@476c21c0 is not valid; is your activity running?

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

8 个答案:

答案 0 :(得分:65)

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

答案 1 :(得分:17)

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

通过这种方式,您将知道指向的活动是否是当前可见活动,否则您的警报将不会显示。

只有当我们在没有完成的情况下在两个活动之间导航时,这才会起作用。

答案 2 :(得分:11)

当后台线程完成其工作并尝试显示对话框时,Activity将在其销毁时发生这种情况。

这个例子很难重现,但是当我们做一些异步任务/后台操作并希望显示一个对话框时就会发生这种情况 活动背景和平均值,而我们的活动由于某种原因正在破坏自己。

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

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

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

答案 3 :(得分:5)

完成网络任务后的后台线程在主线程上调用onSuccess()/ onFailure()回调。如果在那时,启动此后台线程任务的活动不在前台,并且您尝试在onSuccess()/ onFailure()中使用getActivity(),它将为您提供异常。因此,在进行任何UI操作之前,请尝试添加此检查。

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

答案 4 :(得分:4)

是的,您可以检查活动是否有效:Refreshing an Activity from service when Active

此外,如果您的活动处于非活动状态时没有做任何事情,那么您应该在活动停用时取消注册监听器。

答案 5 :(得分:1)

我有两项活动A&amp; B,我只是想知道活动B是否正在运行A.

最初我跟随&#34; RunningTaskInfo&#34;为解决问题,它没有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();
    }

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

此解决方案在我的情况下正常运行..我希望它也能帮到你..

答案 6 :(得分:0)

对于API级别> = 23,您可以使用活动的“生命周期”属性来检测活动状态。这给出了非常紧凑的代码。 这是Kotlin中的示例代码,作为类扩展:

fun FragmentActivity.isRunning() = lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)

// ...
// Here 'myActivity' can be inherited from different activity-like classes, 
// for example, from class AppCompatActivity:
if (myActivity.isRunning()) {
    Log.d("log", "Activity is running!")
}

答案 7 :(得分:0)

如果在关闭活动后不想显示警报对话框或其他操作,请使用此代码。它可以100%准确地工作。

if(!(DownloadVideoActivity.this.isDestroyed()))
{
   //show alert dialog or other things
}