我很惊讶这种(某种)问题如此不受欢迎。
让我先从解决方案开始:
由于ActivityManager.getRunningTasks 自 API 21 起已弃用,
我们必须找到另一种方法来获取 backstack 中的哪些活动。我意识到我们实际上可以实现自己的“堆栈”!
我在 MyOwnApplication 中声明了一个 ArrayList:
private ArrayList<Class> runningActivities = new ArrayList<>();
并添加了访问和修改此列表的公共方法:
public void addThisActivityToRunningActivityies (Class cls) {
if (!runningActivities.contains(cls)) runningActivities.add(cls);
}
public void removeThisActivityFromRunningActivities (Class cls) {
if (runningActivities.contains(cls)) runningActivities.remove(cls);
}
public boolean isActivityInBackStack (Class cls) {
return runningActivities.contains(cls);
}
在所有活动都扩展它的BaseActivity 中:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MyOwnApplication)getApplication()).addThisActivityToRunningActivityies(this.getClass());
}
@Override
protected void onDestroy() {
super.onDestroy();
((MyOwnApplication)getApplication()).removeThisActivityFromRunningActivities(this.getClass());
}
然后您就可以轻松使用isActivityInBackStack 进行检查了。
为什么需要这样做?
是的,当然,大多数情况下都可以通过使用 Intent Flags 和适当的导航来完成。
但是有这样一个用例,我认为应该很常见,我无法简单地通过使用意图标志找到解决方案。
假设我有一个应用程序,它几乎在每个活动中都有一个导航抽屉。
我从MainActivity 导航到ActivityA,然后从ActivityA 创建ChildActivityB。请注意ActivityA 不是ChildActivityB 的父级,因为ChildActivityB 可以从通知等其他活动中打开。
请注意,ChildActivityB 也有一个抽屉。我可以通过抽屉导航到ActivityA,而不是按向上或返回按钮。现在,假设您循环通过这样的过程: Activity A -> ChildActivity B -> Drawer -> Activity A -> ChildActivityB -> Drawer -> Activity A .....
无限活动将在后台创建。
要修复这种行为,我们需要使用 Intent Flags:
(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
到目前为止一切顺利。
但是,我使用overridePendingTransition() 自定义了活动过渡动画。我注意到,如果我将上述意图标志与overridePendingTransition() 放在一起,由于标志Intent.FLAG_ACTIVITY_CLEAR_TOP 导致活动在动画中间被破坏,因此动画会出现故障。
现在,如果我能够检测到ActivityA 是否在后台堆栈中,那么行为将是完美的:
private void navigateToDrawerItems(Class cls) {
drawerLayout.closeDrawer(GravityCompat.END);
Intent intent = new Intent(this, cls);
if (((MyOwnApplication)getApplication()).isActivityInBackStack(cls)) {
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else {
startActivity(intent);
overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
}
}