0

我有一个带有大量活动的 Android 应用程序。堆栈中的一项活动(我们称之为LoginSettings)需要登录到 OAuth 服务。我给了它一个通过Intent. LoginSettings不能使用singleTaskorsingleInstance启动模式,因为它需要保持在其先前活动的堆栈顶部。也就是说,如果用户从 按下堆栈LoginSettings中的先前活动需要显示,并且如果用户稍后重新启动我的应用程序,它无法重新启动显示堆栈中的先前活动。像这样做一样打破中间的堆栈singleTask是没有用的。

我已经使用了网络浏览器和自定义回调 URL 和意图过滤器的技巧,但是因为我不能使用singleTask,我无法将结果放入同一个实例中LoginSettings:它总是创建一个新活动,即使launchModesingleTop。期望的行为是,在用户登录后,浏览器窗口消失并且用户看到LoginSettings,仍然在其后面的堆栈的其余部分。

我想使用浏览器而不是 aWebView来进行身份验证:首先,因为它向用户显示他们正在真正访问目标网站,而不是向我的应用程序提供密码;其次,因为用户可能已经在浏览器中保存了他们的密码(或者可能已经登录)。

4

1 回答 1

0

我最终找到了一个有用的技巧。启动浏览器时LoginSettings,它确保将FLAG_ACTIVITY_NEW_TASK标志添加到Intent启动浏览器的标志。(这可能不会有任何区别,因为singleTask无论如何浏览器都是如此,但最好确定一下。)LoginSettings我没有为我的自定义 URL 提供意图过滤器,而是创建了一个新活动。这个新活动显示为一个对话框,并且allowTaskReparenting在清单中没有。它显示进度条和消息,同时AsyncTask在验证器中进行交易以获取身份验证令牌。完成AsyncTask后,它会调用moveTaskToBack(true)然后完成。这会将包含(仅)浏览器和对话框的任务移到后面,显示上一个任务,其中包含我的活动堆栈导致LoginSettings.

在我的应用程序中,LoginSettings这个新对话框和这个新对话框都使用 OOB 机制与实际管理和存储身份验证凭据的类对话,因此LoginSettings.onResume请与后端检查用户现在是否已登录,如果是则替换登录按钮。作为替代方案,您可以使用广播来传达登录事件,但不要忘记LoginSettings在广播发生时它将处于停止状态。

FLAG_ACTIVITY_NEW_TASK从理论上讲,如果浏览器将标志添加到它启动自定义回调 URL 时,这可能会出错Intent,但我已经用 Firefox 和 Chrome 进行了测试,它与它们完美配合。此外,理论上,包含的任务LoginSettings可能会在后台被破坏。这也是基于解决方案的问题singleTask:您需要为回调 URL 的到达做好准备,onCreate而不是onNewIntent如果发生这种情况。但是使用我的解决方案,由于对话框完成了登录并保存了凭据,因此当用户返回时LoginSettings,即使从头开始重新创建活动,他们也会登录。

于 2013-08-19T12:18:46.550 回答