You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android FLAG_ACTIVITY_NEW_TASK启动页返回后全屏失效方案咨询

问题根因

这是Android跨任务栈启动Activity时的典型System UI状态重置问题:使用FLAG_ACTIVITY_NEW_TASK从Service启动Activity B时,B会运行在独立任务栈中,从B返回A的过程中,系统会重新渲染A的Window,但不会主动恢复A在onCreate阶段设置的沉浸式全屏参数。onCreate中的配置仅在Activity首次创建Window时生效,栈切换导致的Window重绘不会触发这部分逻辑,因此会出现全屏失效。

更优解决方案

不需要在onResume中无脑重复设置全屏参数,以下方案可以从根源上避免状态丢失:

  • 方案1:在主题中静态配置全屏属性(优先级最高,适配成本最低)
    仅靠代码动态设置的参数容易在系统重绘Window时被重置,直接在主题中写死全屏、刘海屏适配相关属性,系统在Window初始化、重绘时都会自动读取配置,不需要额外生命周期处理:

    1. 先在res/values/styles.xml中定义全屏主题:
    <style name="Theme.AppFullScreen" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>
    
    1. 在AndroidManifest.xml中给Activity A、Activity B都指定该主题:
    <activity
        android:name=".ActivityA"
        android:theme="@style/Theme.AppFullScreen" />
    <activity
        android:name=".ActivityB"
        android:theme="@style/Theme.AppFullScreen" />
    
  • 方案2:用官方新API替代已废弃的System UI Flag
    你当前使用的SYSTEM_UI_FLAG_*系列常量在Android 11(API 30)已被废弃,旧API本身存在状态同步缺陷,跨栈切换时极易丢失配置。替换为WindowInsetsController实现后,系统会自动在焦点变化时保持全屏状态:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.setDecorFitsSystemWindows(false)
        val insetsController = window.insetsController
        insetsController?.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
        insetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    } else {
        // 低版本兼容保留原有flag配置,补充全屏相关flag避免遗漏
        val decorView = window.decorView
        val uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                View.SYSTEM_UI_FLAG_FULLSCREEN
        decorView.systemUiVisibility = uiOptions
    }
    
  • 方案3:优化启动模式避免不必要的跨栈启动
    如果Activity B属于应用内页面,不需要独立任务栈,直接去掉FLAG_ACTIVITY_NEW_TASK标记,让两个Activity同属一个任务栈,返回时系统会自动恢复上一个Activity的Window状态,不会出现配置丢失。如果业务确实需要开新任务栈,可以给启动B的Intent补充FLAG_ACTIVITY_CLEAR_TOP标记,保证栈内Window状态一致性。

补充兜底:如果部分定制ROM存在兼容问题,不需要在onResume全量重复设置参数,只需要给DecorView添加OnApplyWindowInsetsListener,监听到Insets变化时校验全屏状态,不符合预期时再重设即可,性能损耗远低于每次生命周期回调无脑赋值。

内容的提问来源于stack exchange,提问作者sodevlei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:54:16