解析ActivityResultLauncher的意外行为:移除FLAG_ACTIVITY_NEW_TASK

323 阅读2分钟

ActivityResultLauncher

在Android开发过程中,我们经常需要处理多个Activity之间的交互。这种情况下,ActivityResultLauncher 是一个非常有用的API,它帮助我们以一种简洁和类型安全的方式处理Activity之间的结果传递。然而,有时候,即使Activity还未结束,ActivityResultLauncher 的回调却意外地被触发,导致了一些困惑。本文将探讨这个问题的起因,并提供解决方案。

场景描述

在我们的应用中,我们希望在用户从后台返回应用时显示一个开屏广告(SplashAdActivity)。为此,我们使用了ActivityResultLauncher来启动这个广告Activity,并期待用户关闭广告后接收到结果。

myActivityResultLauncher.launch(intent);

在我们的初始实现中,我们创建了一个Intent并设置了FLAG_ACTIVITY_NEW_TASK标志,意图是在用户返回应用时启动一个新的任务栈。

Intent intent = new Intent(activity, SplashAdActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

问题分析

预期中,ActivityResultLauncher 的回调应该在SplashAdActivity结束并设置了结果之后才触发。但是,在实际操作中,我们发现回调被立即触发了,这显然是不符合预期的。

Intent Flags的影响

问题的根源在于FLAG_ACTIVITY_NEW_TASK。按照官方文档,当启动一个Activity时,如果设置了这个标志并且任务栈中已经存在该Activity的实例,系统将会把现有的实例带到前台,而不是创建一个新的实例。由于ActivityResultLauncher是基于Activity实例的结果来触发回调的,这就有可能导致立即触发回调,因为系统认为Activity已经结束了。

解决方案

移除FLAG_ACTIVITY_NEW_TASK标志是解决此问题的关键。这样一来,新的SplashAdActivity将在当前任务栈中正常启动,并且ActivityResultLauncher的回调将在Activity真正结束后才触发。

总结

在处理Activity之间的交互时,理解和正确使用Intent flags至关重要。一个看似无关痛痒的标志,可能会导致ActivityResultLauncher等API的行为出现异常。本例中,移除FLAG_ACTIVITY_NEW_TASK解决了意外触发回调的问题,提醒我们在开发过程中需更加留心Intent flags的使用。