9

检查活动是否仍在堆栈中以便回调它的更好方法是什么?

Intent i = new Intent(getApplicationContext(),MyClass.class);
startActivity(i);
4

3 回答 3

6

我很惊讶这种(某种)问题是多么不受欢迎。

让我首先从解决方案开始:
由于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 和适当的导航来完成。
但是有这样一个用例,我认为应该很常见,我无法简单地通过使用意图标志找到解决方案。

假设我有一个应用程序,它几乎在每个活动中都有一个导航抽屉。
我从 导航MainActivityActivityA,然后ChildActivityBActivityA. 请注意,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在 backstack 中,那么行为将是完美的:

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);
    }
}
于 2017-09-14T04:07:16.177 回答
0

查看ActivityManager API

要获取 ActivityManager 的实例,请使用以下代码:

ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
于 2012-12-20T11:11:31.973 回答
0

您可以将全局变量切换为特定类内部onCreate()onDestory()特定类的指示器,或者ActivityLifecycleCallbacks内部onActivityCreated()和内部的指示器。onActivityDestroyed()

例如:

  registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {

      @Override
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
          if (activity instanceof YourActivity) {
              myGlobalData.setActExist(true);
          } 
      }

      @Override
      public void onActivityDestroyed(Activity activity) {
          if (activity instanceof YourActivity) {
              myGlobalData.setActExist(false);
          }
      }
  });
于 2018-09-26T12:40:30.363 回答