如何判断Intent是否为启动App的初始Intent而非内部导航Intent?
我们需要针对deeplink启动的Intent做特殊UI处理,但目前通过deeplink启动App时这个处理效果不佳。当前我们通过给Intent额外添加布尔值来区分两类Intent,但想了解Android框架/SDK中是否有原生方法可判断某一Intent是否为App启动Intent。
注:我们使用Jetpack Navigation处理传入的Intent/deeplink并做内部路由,因此会从
currentBackStackEntry中获取Intent。
当前已实现的方案
在MainActivity的onCreate中标记启动Intent:
intent.putExtra(KEY_IS_APP_CREATED_INTENT, true)
在UI逻辑中读取标记:
val isAppCreationIntent = navController.currentBackStackEntry?.arguments?.parcelable<Intent>(KEY_DEEP_LINK_INTENT)?.getBooleanExtra(KEY_IS_APP_CREATED_INTENT, false) ?: false
原生判断方案
以下几种原生方式可替代自定义标记:
1. 利用Activity的isTaskRoot()与Intent标志位
当App首次冷启动时,当前Activity是任务栈的根节点,isTaskRoot()会返回true;同时启动Intent通常带有FLAG_ACTIVITY_NEW_TASK或FLAG_ACTIVITY_CLEAR_TASK标志。
示例代码:
// 在Activity中判断 val isLaunchIntent = isTaskRoot && intent.hasFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
注意:若App处于后台时通过deeplink启动了新的Activity实例(取决于启动模式),
isTaskRoot()也会返回true,需结合应用前后台状态进一步判断。
2. 通过全局生命周期回调追踪启动状态
注册Application.ActivityLifecycleCallbacks,记录应用是否为首次启动:当第一个Activity的onCreate触发且无其他活跃Activity时,标记为启动状态;后续收到的Intent则判定为内部导航Intent。
3. 结合Jetpack Navigation的deeplink监听
使用OnDeepLinkListener监听deeplink触发事件,同时通过ActivityManager判断应用是否处于前台:若应用未在前台,当前deeplink Intent即为启动Intent;反之则为内部导航Intent。
注意事项
- 若应用使用
singleInstance、singleTask等特殊启动模式,isTaskRoot()的判断逻辑需根据实际场景调整。 - 当App从后台被唤醒并处理deeplink时,
isTaskRoot()可能返回false,此时需结合应用的前后台状态综合判断Intent类型。
内容的提问来源于stack exchange,提问作者dazza5000

