我在某个活动中遇到了监听器的问题。
问题是这个监听器包含一个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的监听器中检查此活动是否处于活动状态,然后根据此值显示警告?
答案 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
}