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

时间:2011-05-12 09:15:13

标签: android android-activity lifecycle

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

10 个答案:

答案 0 :(得分:141)

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

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

我希望这会有所帮助

答案 1 :(得分:102)

更新(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

的更多信息


答案 2 :(得分:15)

there is an easiest solution to this, you can use isTaskRoot() in your activity

答案 3 :(得分:5)

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

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

答案 4 :(得分:4)

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

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

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

然后你可以这样检查:

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

答案 5 :(得分: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);

答案 6 :(得分: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

答案 7 :(得分:2)

希望这对新手有帮助,基于以上对我有用的答案,我也共享代码段,因此易于实现。

解决方案::如果当前活动仅是您堆栈中的活动,并且不是我,则我使用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();
        }

    }

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

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