在旧版SDK中清除完整的Android活动堆栈(缺少FLAG_ACTIVITY_CLEAR_TASK标志)

12
我已经在 Stack Overflow 上进行了一些阅读和搜索,但找不到一种方法来清除当前的 Activity 栈。我的应用程序背景下是一个由后台服务/通知启动的活动。
假设我的应用程序允许您组织人员列表。几个小时前,您正在查看“查看”活动中的 “人员 X”,这是您的堆栈顶部。在将来的某个时候,服务触发器会弹出新的“通知”活动,以编辑“人员 Y”的详细信息。
当您完成此活动时,弹出堆栈并最终查看人员 X,这将是混乱的用户体验。理想情况下,我想回到用户正在做的任何事情(电子邮件等…),或者至少回到我的应用程序主页。
我尝试使用 FLAG_ACTIVTY_NEW_TASK 启动 "Notify",但似乎没有帮助:当任务完成时,它只是返回到先前的任务。我想要的似乎是 Android 3 的新 FLAG_ACTIVITY_CLEAR_TASK,但在之前的 SDK 中不存在。
有人有实现这一目标的建议吗?

1
你可能会发现IntentCompat类很有用:https://dev59.com/LGIk5IYBdhLWcg3wiuqk - Hassan Ibraheem
3个回答

20

只需全部杀掉

您可以通过使用BroadcastReceivers来实现:

  • 创建一个像这样的BaseActivity

public class BaseActivity extends GuiceActivity {
    private KillReceiver mKillReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mKillReceiver = new KillReceiver();
        registerReceiver(mKillReceiver,
            IntentFilter.create("kill", "spartan!!!"));
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mKillReceiver);
    }
    private final class KillReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    }
}
  • 让你的活动扩展自BaseActivity
  • 每当您想要清除堆栈时:

Intent intent = new Intent("kill");
intent.setType("spartan!!!");
sendBroadcast(intent);


谢谢Cristian。既然返回主页是可以接受的,我想我会选择另一个稍微简单一些的建议。不过如果我想要不留任何其他程序运行,这看起来是一个很好的解决方案。 - Romain
3
在清除其余活动堆栈并启动不在历史堆栈中的活动时非常有效。"spartan!!!" MIME 类型很有趣,但会抛出 RuntimeException 异常:错误的 MIME 类型。应该将其更改为 "text/plain" 以便示例按原样工作。:P 还有,您应该将 kill intent 的名称更改为 maliciousIntent - dvs
8
这完全是错误的。它没有考虑到Android的工作方式。比方说,如果系统(例如低内存)杀掉了任务中的一个Activity,那么这个Activity不会被BroadcastReceiver杀掉,因为它已经被系统杀掉了。问题在于,它将继续留在后台堆栈中。 - Cyril Mottier
这取决于您想要的结果...对于通过密码网关进行单个实例输入,这是在Android 12之前缺乏堆栈功能的完美解决方法。 - Dan

6

如果您已经在堆栈中运行了应用程序主页的实例,当活动Y完成时,您可以使用标志FLAG_ACTIVITY_CLEAR_TOP启动您的应用程序主页(使用startActivity())。由于它已经在堆栈上,而不是创建一个新实例,这将使您返回到您的应用程序主页并清除其顶部的堆栈。


谢谢!我太专注于FLAG文档,完全忽略了这一点。我想如果主页活动没有启动,它只会启动一个新的,这并不是真正的问题。这应该绝对可以解决它。 - Romain
我想补充一下,从onStop()中调用startActivity(HOME)会导致一些闪烁。相反,在调用finish()之前和onBackPressed()中我进行了调用。 - Romain
我自己也曾经为了解决Activity堆栈的问题而苦苦挣扎,我知道让我们的应用程序达到我们想要的效果并不容易。至于闪烁问题,我以前从未注意到过...但这是个不错的补充! - Rodrigo Chiossi

0
在编程方面,创建一个ArrayList并将所有活动对象保存到每个活动的onCreate()中。每当您想要完成特定活动时,只需从ArrayList检索该活动实例并完成它。

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