android:clearTaskOnLaunch无效 如何在返回前台时清除后退栈?

3
我需要在我的应用程序中实现以下行为:“每次用户尝试启动应用程序(直接点击应用程序图标,或通过任务管理器或最近使用的应用程序),都必须登录一次。”因此,活动的顺序如下(假设应用程序名称为Foo app):
- S - 启动屏幕 - L - 加载屏幕 - Lo - 登录屏幕 - M - 主菜单(包含任务列表) - T - 任务屏幕
“用户启动应用程序并按以下顺序进行操作:
S -> L -> Lo(登录)-> M(选择一个任务)-> Task Screen”
所以,当他在任务屏幕上时,他按Home按钮,应用程序进入后台,他使用另一个应用程序。然后再次启动Foo应用程序。如果按Back按钮,则会显示先前使用的Task Screen???如果再次按Back按钮,则会返回到Main screen,以此类推...???
这不应该发生,我想要的是,当应用程序回到前台时,用户需要登录,并且永远不能返回任何屏幕。
请注意:所有屏幕都扩展了BaseActivity类,该类已扩展了Activity类。我在其中使用了onResume(),onPause()方法和另一个自定义方法来确定扩展子类何时暂停,并在应用程序从后台返回时恢复!在某些屏幕中,我还不得不使用片段...!
非常感谢您的时间和帮助!

因为重复问题被踩低了这里(顺便说一下,这是一个非常好的回答),以及这里 - verybadalloc
如果用户按下Home键或其他活动置于顶部(如来电界面),那么当用户通过应用程序图标或返回键返回到您的活动时,他应该期望看到您的应用程序在原处。我还没有见过一个严肃和流行的Android应用程序表现得不同...我不认为它不应该这样表现。 - gunar
首先感谢两位的评论。 @verybadalloc 嘿,我在发布这个问题之前也看到了那个答案,但是我已经在我的应用程序中实施了那些东西,但是没有得到期望的结果!:( - Randika Vishman
@gunar 你好,如果你能想象一下一个应用程序,你可以通过该应用程序隐藏或锁定所有你选择的图像,并且每次需要访问这些图像时,你必须通过该应用程序登录,而不是直接在该应用程序的最近查看的照片库中。因此,为了实现这种行为,我们需要实现上述提到的场景。 - Randika Vishman
当Activity的backStack如下所示 A -> B -> C -> D 当用户在D中按Home键时, 无论以后以何种方式启动应用程序,我都希望他回到A活动,就像简单地弹出堆栈直到A!因为它是登录活动 我仍然无法解决这个问题! 我可以在应用程序的任何地方找到它,当它从后台返回前台时,并通过FLAG_ACTIVITY_CLEAR_TASK传递一个Intent到StartActivity方法,而且我已经在使用**android:clearTaskOnLaunch="true"**, 但问题仍然存在! - Randika Vishman
2个回答

0

在清单文件的根(主要)活动标签中添加标签android:clearTaskOnLaunch="true"。这样用户就会始终返回到该活动。

要从其他任何活动跳转到登录,请使用:

public static void logoff(Context c){
    Intent logoff = new Intent(c,LoginActivity.class);
    logoff.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    c.startActivity(logoff);
}

嗨,谢谢回复, 我想我做了同样的事情,但实际上那并没有起作用!不管怎样,创建静态方法的原因是什么? 何时调用?我的问题实际上是我也做了同样的事情,并成功启动了新的登录活动或可以转到闪屏界面,但问题在于此时如果用户点击返回按钮,他/她仍然可以访问上一个Activity,即他上次使用它时使用的Activity! :( (需要这种行为,以避免提供应用程序内信息的保护) 有任何帮助吗? - Randika Vishman
@Vishman,“logoff”方法会按照其字面意思执行,它将把用户从任何其他活动带回到登录活动。用户无法通过按返回键来撤消此操作,因为它结束了旧任务并启动了一个新任务。这是静态的,因此可以轻松地从任何地方调用它。现在,在清单中的登录活动中添加“android:clearTaskOnLaunch =“true””将确保当用户去其他地方并返回应用程序时,他将进入登录活动,并在刷新的新任务中(就像“logoff”方法一样)。此外,我建议在登录活动中使用片段,并将闪屏/加载/登录片段仅放置在登录活动中。 - S.D.
嗨,感谢您的解释,我会尝试并告知您结果,好吗? - Randika Vishman
当Activity的backStack如下所示 A -> B -> C -> D 当用户在D中按Home键时, 无论以后以何种方式启动应用程序,我都希望他回到A活动,就像简单地弹出堆栈直到A!因为它是登录活动 我仍然无法解决这个问题! 我可以在应用程序的任何地方找到它,当它从后台返回前台时,并通过FLAG_ACTIVITY_CLEAR_TASK传递一个Intent给StartActivity方法,而且我已经在使用**android:clearTaskOnLaunch="true"**, 但问题仍然存在! - Randika Vishman
很抱歉,大家可能会觉得这有点傻,但是我通过获取以下答案的帮助找到了我的问题的一半解决方案:answer希望这对你们有所帮助,如果你们遇到同样的问题。 - Randika Vishman

0
我不会争辩你的问题描述了一个不那么愉快的用户体验,但是以下解决方案你怎么看?
Lo, MT 替换为片段。所以在 L 后面,您将拥有一个活动(PostL),在该活动中您将首先显示 Lo 片段,然后在用户操作上,您将通过 get(Supported)FragmentManager.beginTransation().add(id, fragment).commit() 在Lo顶部添加 M 片段,然后继续移动,您将通过 get(Supported)FragmentManager.beginTransation().replace(id,fragment).commit() 将 M 替换为 T - 或者您可以在 M 的顶部添加 T,这取决于它可能更适合。
在此 PostL 活动中,在 onPause() 方法中,如果该片段回退栈包含多个片段 - 底部片段是 Lo,则只需调用 get(Supported)FragmentManager.popBackStack() 即可。

这样,当用户点击主屏幕并重新进入应用程序(无论从何处),或任何其他应用程序进入前台时,都将被覆盖。此外,如果正确考虑返回堆栈大小,如果用户返回,则始终会打开最后一个片段(可能是 M 或 Lo)。

我希望这有意义...


首先感谢您的建议。但是这似乎是一个全新的开发分支变化,而我现在已经完成了大部分的产品。无论如何,非常感谢,如果我无法通过其他方式解决这个问题,我也会尝试这个解决方案,并且一定会告诉您结果,好吗?再次感谢! - Randika Vishman
你不应该有那么多工作要做,因为将“Activity”迁移到“Fragment”或者反过来是相对容易的。它们的生命周期非常相似,回调函数也类似,所以你不应该有太多工作量。你可以花2个小时来尝试,如果可以的话就好了,如果不行,你可以保持原样。 - gunar
谢谢你的帮助! 所以,如果我选择这个解决方案,我就必须将所有其他任务从Activity迁移到Fragment的方式,对吗?如果不这样做,以后可能会出问题。 - Randika Vishman
很抱歉,大家可能会觉得这有点傻,但是我通过获取以下答案的帮助找到了我的问题的一半解决方案:answer希望这对你们有所帮助,如果你们遇到同样的问题。 - Randika Vishman
看一下那个答案中Radu的评论。那是一个不太正规的什么都不做的方法。 - gunar
这是一眼看上去就是真的。但是基于那个答案,我使用了自定义方法来检测它何时来自后台,并且我给出链接的那个答案,我只解决了一半的问题。当用户点击应用程序图标并将应用程序转到前台时,意外地清除了后退堆栈。但是如果用户在最近的应用程序中访问它,则仍然存在相同的问题,即用户能够访问以前的活动。:( 我甚至不想记起那个头疼的经历!!! - Randika Vishman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接