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

Xamarin.Forms iOS点击非活跃状态推送通知后应用卡在启动屏问题

问题成因

  • 启动流程与推送跳转逻辑互锁:自定义视频启动屏需要等播放完成才会将UIWindow的根控制器切换为Xamarin.Forms应用的主控制器,前台点击推送后存储的全局待跳转标记/推送数据未在应用销毁时清空,冷启动时FinishedLaunching读取到残留标记直接执行跳转逻辑,但此时主控制器还未初始化完成,两个逻辑互锁导致卡死。
  • UIWindow层级管理混乱:部分视频启动屏实现方案会单独创建新的UIWindow层级覆盖在主Window之上播放视频,推送跳转逻辑默认向主Window的导航栈Push页面,此时主Window被启动屏Window遮挡、且跳转执行时启动屏Window未被正确释放,会出现主页面加载完成但被遮挡,或跳转找不到有效导航栈的白屏问题。
  • 应用状态判断错误:应用非活跃状态收到推送后点击图标启动时,若错误将该场景判定为需要处理推送跳转,未判断启动流程是否完成就直接执行跳转,启动屏的dismiss逻辑和页面跳转逻辑同时操作根控制器,会引发控制器层级异常导致卡顿。

解决方案

1. 统一启动状态标记与缓存清理机制

  • 新增全局布尔标记isLaunchCompleted,默认值为false,仅当视频启动屏播放完成、Xamarin.Forms主应用根控制器完全加载后才设为true。
  • 应用退到后台或被销毁前,清空所有全局存储的待跳转推送数据、跳转标记,避免冷启动读取到残留的无效数据。
  • 新增推送数据有效性校验逻辑,冷启动时读取到的推送如果生成时间超过5分钟直接丢弃,不执行跳转。

2. 调整推送跳转的执行时机

  • 封装所有推送跳转逻辑为独立方法HandlePendingNotification(),禁止直接在FinishedLaunching方法中执行跳转。
  • 冷启动时如果收到推送,先将推送数据存入全局变量缓存,等待isLaunchCompleted变为true后,再延迟300毫秒执行跳转逻辑,确保主导航栈已完全初始化。
  • 前台运行状态收到推送时,直接判断isLaunchCompleted为true即可立即跳转,无需缓存。

3. 优化UIWindow层级与启动兜底逻辑

  • 整个应用仅保留一个全局UIWindow实例,视频启动屏作为根控制器的子视图/子控制器展示,不要单独创建新的Window层级。
  • 给视频启动屏增加3秒兜底超时逻辑,无论视频是否播放完成,3秒后强制dismiss启动屏,切换主应用根控制器并将isLaunchCompleted设为true,避免启动流程永久卡死。

代码示例(AppDelegate.cs修改参考)

public static class GlobalConfig
{
    public static bool isLaunchCompleted = false;
    public static NSDictionary PendingNotification = null;
}

[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        Window = new UIWindow(UIScreen.MainScreen.Bounds);
        
        // 初始化视频启动屏控制器
        var videoSplashVC = new VideoSplashViewController();
        Window.RootViewController = videoSplashVC;
        Window.MakeKeyAndVisible();

        // 缓存冷启动推送数据,暂不处理
        if (options?.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey) == true)
        {
            GlobalConfig.PendingNotification = options[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
        }

        // 启动屏完成回调
        videoSplashVC.OnSplashFinished += () => 
        {
            // 加载Xamarin.Forms主应用
            LoadApplication(new App());
            GlobalConfig.isLaunchCompleted = true;
            
            // 延迟处理待跳转推送
            DispatchQueue.MainQueue.DispatchAfter(
                new DispatchTime(DispatchTime.Now, 300 * TimeSpan.NanosecondsPerMillisecond), 
                () =>
            {
                if (GlobalConfig.PendingNotification != null)
                {
                    HandlePendingNotification(GlobalConfig.PendingNotification);
                    GlobalConfig.PendingNotification = null;
                }
            });
        };

        return base.FinishedLaunching(app, options);
    }

    private void HandlePendingNotification(NSDictionary notificationData)
    {
        // 你的原有推送跳转逻辑
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:15:01