如何检查活动是否是应用程序活动堆栈中的最后一个活动?

问题描述 投票:106回答:10

我想知道如果退出当前活动,用户是否会返回主屏幕。

android android-activity lifecycle
10个回答
104
投票

更新(2015年7月):

由于getRunningTasks()被弃用,从API 21开始,最好遵循raukodraug answer或Ed Burnette one(我更喜欢第二个)。

可以使用ActivityManager检查当前任务及其堆栈。

因此,要确定活动是否是最后一个:

  • 请求清单中的android.permission.GET_TASKS权限。
  • 使用以下代码: ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE ); List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10); if(taskList.get(0).numActivities == 1 && taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) { Log.i(TAG, "This is last activity in the stack"); }

请注意,上述代码仅在您有单个任务时才有效。如果您的应用程序可能存在多个任务 - 您需要检查其他taskList元素。阅读有关任务Tasks and Back Stack的更多信息


0
投票

这里错过的一件事是“Home键”点击,当你激活时,你无法从你的活动中检测到这一点,所以最好以编程方式控制活动堆栈,处理“后退键”按下并移动到所需的活动或只是做了必要的步骤。

此外,您无法确定是否可以通过将一些额外数据预设为打开活动的意图来检测从“最近活动”列表开始您的活动,因为在这种情况下可以重复使用。


144
投票

我将发布@H9kDroid的评论作为有类似问题的人的最佳答案。

您可以使用isTaskRoot()来了解活动是否是任务的根。

我希望这有帮助


15
投票

有一个最简单的解决方案,你可以在你的活动中使用isTaskRoot()


5
投票

虽然可能有办法实现这一点(见其他答案),但我建议你不要这样做。普通的Android应用程序不需要知道主屏幕是否即将显示。

如果您正在尝试保存数据,请将数据保存代码放在onPause()方法中。如果您试图让用户改变他们对现有应用程序的看法,您可以截取Back键和onBackPressed()方法的向上/向下键,并向他们显示“你确定吗?”提示。


4
投票

跟踪此问题的一种方法是在开始新活动时包含标记并检查标记是否存在。

每当您开始新活动时,请插入标记:

newIntent=new Intent(this, NextOne.class);
newIntent.putExtra(this.getPackageName()+"myself", 0);
startActivity(newIntent);

然后你可以这样检查它:

boolean islast=!getIntent().hasExtra(this.getPackageName()+"myself")

3
投票

使用ActivityManager的sandrstar解决方案的问题是:您需要获得以这种方式获取任务的权限。我找到了一个更好的方法:

getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)

堆栈底部的Activity默认情况下应该总是得到这个类别,而其他活动不应该得到它。 但即使在某些设备上失败,您也可以在启动Activity时进行设置:

Intent intent = new Intent(startingActivity, SomeActivityClass.class);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
activity.startActivity(intent);

3
投票

希望这会对初学者有所帮助,基于以上对我有用的答案,我也在共享代码片段,因此很容易实现。

解决方案:我使用isTaskRoot(),如果当前活动只是你的堆栈中的活动而返回true,除了我还处理如果我在堆栈中有一些活动的情况下转到堆栈中的最后一个活动而不是打开新的自定义一个。

在你的活动中

   @Override
    public void onBackPressed() {

        if(isTaskRoot()){
            startActivity(new Intent(currentActivityName.this,ActivityNameYouWantToOpen.class));
            // using finish() is optional, use it if you do not want to keep currentActivity in stack
            finish();
        }else{
            super.onBackPressed();
        }

    }

2
投票

我为我的所有活动创建了一个基类,扩展了AppCompatActivity,并且有一个静态计数器:

public abstract class BasicActivity extends AppCompatActivity {
    private static int activityCounter = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ++activityCounter;
        ...
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        --activityCounter;
        if(activityCounter==0) {
            // Last instance code...
        }
    }

    public boolean isLastInstance() { return (activityCounter==1); }
}

到目前为止,这已经足够好了;而且无论API版本如何。当然,它要求所有活动扩展这个基类 - 就我而言,它们都是这样做的。

编辑:我注意到一个实例,当计数器在应用程序完全退出之前降至零时,即更改方向并且只打开一个活动时。当方向改变时,活动被关闭而另一个被创建,因此为最后一个活动调用onDestroyed,然后在使用改变的方向创建相同活动时调用onCreate。必须考虑到这种行为;可能会使用OrientationEventListener


0
投票

Android实现了一个Activity堆栈,我建议你读一下here。看起来你想要做的就是检索调用活动:getCallingActivity()。如果当前活动是您的应用程序中的第一个活动,并且应用程序是从主屏幕启动的,那么应该(我假设)返回null

© www.soinside.com 2019 - 2024. All rights reserved.