检查活动是否有效
我在某个活动中遇到了一个听众的问题。
问题是这个监听器包含一个alert.show(); 这可以在我们试图推出一个新的活动(然后给出一个例外)之后被调用。
例如:我正在收听来自另一部手机的信号。 我按回来尝试运行一个新的活动B,但由于alert.show()的监听器,程序崩溃。
ERROR/AndroidRuntime(3573): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@476c21c0 is not valid; is your activity running?
我可以在A的监听器中检查此活动是否处于活动状态,然后根据此值显示警报吗?
可能有一种我想不出的简单方法,但一种方法是自己实现它。 在onResume()
您将成员variablesmIsRunning
设置为true,并将onPause()
为false。 使用这个布尔值,你应该知道不要在你的callback中调用alert.show()
。
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() }
通过这种方式,您将知道指向的活动是否是当前可见的活动,否则您的警报将不会显示。
这只会在两个活动之间没有完成的情况下导航。
当后台线程完成其工作并尝试显示一个对话框时,活动将会经历其销毁。
这个例外是罕见的重现,但是当我们做一些asynchronous的任务/背景操作,并希望显示与活动上下文的对话,而在我们的活动正在由于某种原因而正在销毁自己的对话。
Android操作系统应该处理这种情况,但到目前为止它不。
所以在调用你的对话之前,只要检查活动是否正在运行,而不是在其销毁阶段。
if(!isFinishing()){ callDialog(); }
是,您可以检查活动是否处于活动状态: 活动时刷新活动服务
另外,如果您的活动处于非活动状态时没有做任何事情,那么当您的活动取消激活时,您应该取消注册监听者。
后台线程完成其networking任务后,调用主线程上的onSuccess()/ onFailure()callback函数。 如果在那个时候,启动这个后台线程任务的活动不在前台,并且你尝试在onSuccess()/ onFailure()中使用getActivity(),它会给你例外。 所以尝试在做任何UI操作之前添加这个检查。
if(!((Activity) context).isFinishing()) { //show alert }
我有两个活动A和B,我只是想知道活动B是否从A运行。
最初我跟着“RunningTaskInfo”来解决问题,它不是100%的工作。
所以我创build了自己的解决scheme,我会发布我的解决scheme 使用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); } }
}
现在在Activity 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(); }
………………………………..
这个解决scheme在我的情况下正常工作..我希望它会帮助你。