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

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

106811 次浏览

跟踪这一点的一种方法是在启动新活动时包含一个标记,并检查该标记是否存在。

无论何时开始一个新的活动,插入标记:

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

然后你可以这样检查:

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

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

最新情况(2015年7月) :

因为 GetRunningTasks ()已经被废弃了,所以从 API 21开始,最好遵循 Raukodraug 回答Ed Burnette (我更喜欢第二个)。


有可能使用 活动经理检查当前任务及其堆栈。

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

  • 在清单中请求 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");
    }
    

Please note, that above code will be valid only if You have single task. If there's possibility that number of tasks will exist for Your application - You'll need to check other taskList elements. Read more about tasks Tasks and Back Stack


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

如果要保存数据,请将数据保存代码放在 onPuse ()方法中。如果您试图让用户改变他们对应用程序存在的看法,那么您可以截获 Back key 和 onBackPress ()方法的密钥 up/down,并向他们显示一个“ Are you sure?”提示。

这里错过的一件事是“主键”点击,当激活时,你无法从你的活动中检测到这一点,所以最好通过处理“后键”按钮和移动到所需的活动或只是做必要的步骤来程序化地控制活动堆栈。

此外,您不能确定是否可以通过预先设置一些额外的数据来检测从“最近活动”列表开始的活动,以便打开活动,因为在这种情况下会重用这些数据。

我要改进的评论 @ H9kDroid作为最好的答案,这里的人们有一个类似的问题。(原版 链接)

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

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

getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)

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

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

有一个最简单的解决方案,你可以使用 < a href = “ http://developer.android.com/reference/android/app/Activity.html # isTaskRoot ()”rel = “ noReferrer”> isTaskRoot () 在你的活动中

我已经为所有活动创建了一个基类,扩展了 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

希望这将有助于新手,基于以上的答案,我的工作很好,我也分享代码片段,所以它将很容易实现。

解决方案: 我使用 isTaskRoot(),如果 当前活动只是堆栈中的活动返回 没错,其他我也处理这种情况,如果 我在堆栈中有一些活动去堆栈中的最后一个活动,而不是打开新的定制一个。

在你的活动中

   @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();
}


}