【发布时间】:2011-08-23 23:10:44
【问题描述】:
我想知道如果用户退出当前活动,他是否会返回主屏幕。
【问题讨论】:
-
刚刚发现 Activity 中有一个名为 isTaskRoot 的函数,我想这对你有帮助。
标签: android android-activity lifecycle
我想知道如果用户退出当前活动,他是否会返回主屏幕。
【问题讨论】:
标签: android android-activity lifecycle
【讨论】:
if (isTaskRoot()) { // do something }
更新(2015 年 7 月):
由于 getRunningTasks() 已被弃用,从 API 21 开始,最好遵循 raukodraug answer 或 Ed Burnette one(我更喜欢第二个)。
可以使用ActivityManager 检查当前任务及其堆栈。
所以,要确定一个活动是否是最后一个:
使用以下代码:
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
【讨论】:
isTaskRoot() 方法以正确的方式进行操作。
希望这将有助于新的初学者,基于上面的答案对我来说很好,我也分享代码 sn-p 所以它很容易实现。
解决方案:我使用了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();
}
}
【讨论】:
有一个最简单的解决方案,你可以使用isTaskRoot() 在你的活动中
【讨论】:
跟踪这一点的一种方法是在您开始新活动时包含一个标记并检查该标记是否存在。
每当您开始一项新活动时,插入标记:
newIntent=new Intent(this, NextOne.class);
newIntent.putExtra(this.getPackageName()+"myself", 0);
startActivity(newIntent);
然后你可以像这样检查它:
boolean islast=!getIntent().hasExtra(this.getPackageName()+"myself")
【讨论】:
虽然可能有办法实现这一点(请参阅其他答案),但我建议您不要这样做。普通的 Android 应用程序不需要知道主屏幕是否即将显示。
如果您要保存数据,请将数据保存代码放在您的 onPause() 方法中。如果您试图让用户改变他们对现有应用程序的看法,您可以拦截 Back 键和 onBackPressed() 方法的向上/向下键,并向他们显示“您确定吗?”提示。
【讨论】:
我为我的所有活动创建了一个基类,扩展了 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 可能会被使用。
【讨论】:
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);
【讨论】:
Android 实现了一个 Activity 堆栈,我建议你阅读它here。看起来您想要做的只是检索调用活动:getCallingActivity()。如果当前活动是您的应用程序中的第一个活动,并且应用程序是从主屏幕启动的,它应该(我假设)返回 null。
【讨论】:
这里错过的一件事是“主页键”单击,当激活时,您无法从活动中检测到这一点,因此最好通过处理“返回键”按下并移动到以编程方式控制活动堆栈必要的活动或只是做必要的步骤。
此外,您不能确定是否可以通过将一些额外数据预设为打开活动的意图来检测从“最近活动”列表启动活动,因为在这种情况下会重复使用。
【讨论】: