我最近迁移到使用 Android 12 的新 SplashScreen API 并删除了自定义启动活动。
MainActivity
始终具有 launchMode = singleTask
,以避免在深度链接等时多次重新创建它。这也是根据 Android 文档推荐的
launchMode
。
这是我的原始清单:
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
使用此清单,如果我打开任何其他活动,按 Home 并通过应用程序启动器再次打开应用程序,导航将重置回 MainActivity (预期,因为启动模式)。我的问题是为什么这是推荐的方式,但同时没有维护返回堆栈的规定?
如果我删除
launchMode
(默认为 standard
),每次我从启动器启动它时,我都会看到 Activity 的 onCreate
被调用,这会再次显示启动画面 - 这是不可取的。我错过了什么吗?
将 singleTask 与 MainActivity 结合使用并结合 Android 12 的新 SplashScreen API 确实可以创建您所描述的行为。这种启动模式可以防止创建 MainActivity 的多个实例,这对于深度链接或其他单入口情况很有帮助。但是,正如您所注意到的,当通过启动器重新打开应用程序时,它可能会导致导航重置,从而清除后堆栈。
以下是可能有助于实现所需行为的几种方法的细分:
选项 1:使用 FLAG_ACTIVITY_NEW_TASK
一种替代方法是对 MainActivity 使用 launchMode="standard" 并在任何意图中添加 FLAG_ACTIVITY_NEW_TASK ,将其带到前台执行特定任务(例如来自通知或深层链接)。这允许您维护返回堆栈,同时在任务已存在的情况下仍然防止出现多个实例。
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
选项 2:使用 singleTop 作为妥协
singleTop 也可以是一个选项,它允许重用 MainActivity 的现有实例(如果它已经位于堆栈顶部),从而避免重置行为。当 MainActivity 不在顶部时,这可能会导致出现多个实例,但它可以帮助防止启动画面重复显示。
每个选项都有权衡,因此测试哪种方法最符合您的导航要求是关键。如果您想更详细地探索其中之一,请告诉我!