【真机Bug】异步加载资源未完成访问单例导致资源创建失败

1.错误表现描述

抽卡时,10抽展示界面为A。抽取内容可能是整卡或者碎片,抽到整卡,会有立绘展示和点击详情的按钮。
点击详情后出现详情页B。【此时界面A预制体被销毁,卡片数据进入数据缓存池】
点击页面B的返回按钮,单例的HuanLingRewardController读取DataPool的内容加载界面。
Bug表现:10抽的抽卡展示界面没有出现。
【P.S. 测试发现,问题在游戏引擎平台上没有任何问题,在真机中稳定复现
image.png

2.错误排查阶段

因为界面B没有显示,那么就可能有下面几种情况

  1. 界面B的最大一级预制体没有创建/或者被隐藏
  2. Grid下的每个Item可能没有被创建成功/或者被隐藏

通过对指定卡片的GameObject进行addWatches 监视 和 对于SetActive位置进行断点。
首先排除了,物品未被激活导致不显示的问题。

然后从返回按钮的点击事件回调,追踪了一下上下文结构。在机器适配过程中发现,代码中并没有专门为webgl编写相关的宏分支。那么初步可以判断问题不是出现在机型适配导致的。

接下来,我在CreateItem方法和HuanLingRewardController脚本的Awake和OnEnable阶段断点。
查看堆栈。追踪一下上下文。
image.png
在绘制界面的必经方法中打印了日志(真机调试,用日志输出)
然后。
对比正常创建10抽界面(第一次十抽后显示)和 详情页返回10抽界面(Bug不显示)的日志
image.png
上图为正常加载界面,可以看到碎片都成功加载了。
image.png
上图为不显示界面的情况。发现HuanLingRewardController.awake 阶段在showDrawResult后执行的。
看看awake做了什么事

 private void Awake(){Debug.LogWarning("HuanLingRewardController.Awake()执行了");m_Instance = this;if (!CheckUI()) return;m_LiHuiView.PlayFinished = OnPlayFinished;m_LiHuiView.UpdateActiveTips = OnUpdateActiveTips;m_AutoActiveTipsTweeners = m_AutoActiveTips.GetComponents<UITweener>();m_AutoActiveTips.gameObject.SetActive(false);}

他对Instance实例初始化了。
因为实际上awake在后面执行,所以此时m_Instace == null ,然后在if (!m_Instance) return; 返回了

 public static void ShowDrawResult(GC_SPIRITS_LOTTERY packet, bool playTweenAnimation = true){Debug.LogWarning("ShowDrawResult执行了");if (!m_Instance) return;m_Instance.InnerShowDrawResult(packet, playTweenAnimation);}

3.错误分析

那么为什么作为单例的Controller的awake阶段会在他的静态方法执行后才初始化。
之前的写法是

 public static void ShowLastReward(){Debug.LogWarning("ShowLastReward()执行了");if (m_LastSpiritsLotteryPacket == null) return;ShowUI(SubPage.Reward,true);HuanLingRewardController.ShowDrawResult(m_LastSpiritsLotteryPacket);}

如果ShowUI是同步加载资源的话,是没有问题的但实际上showUI的基类会调用

private static bool DoShowUI(bool bSync, UIPathData pathData, OnOpenUIDelegate delOpenUI = null, object param = null)

 AssetManager.LoadUI(pathData.path, m_instance.LoadUIBundleFinish, pathData);
//主要是调用了LoadUI
pathData.onOpenUI = delOpenUI;
pathData.param = param;
AssetManager.LoadUI(pathData.path, m_instance.LoadUIBundleFinish, pathData);

而LoadAsset是一个异步加载的原型

public static void LoadAsset(BundleType type, string name, Action<IAssetRef, object> callback, object param){if (string.IsNullOrEmpty(name))return;
#if USE_ABBundleTask task = new BundleTask(OnLoadRemoteAssetFinished);task.AddParam(param);task.AddParam(callback);task.Add(type, name);LoadBundle(task, AssetLoader.LoadQueueType.KEYRES);
#elseif (RemoteBundleManager.IsRemoteBundle(type, name)){BundleTask task = new BundleTask(OnLoadRemoteAssetFinished);task.AddParam(param);task.AddParam(callback);task.Add(type, name);LoadBundle(task, AssetLoader.LoadQueueType.KEYRES);}else if (Zeus.Framework.Asset.LocalAssetStatus.Ready == Zeus.Framework.Asset.AssetManager.GetAssetStatus(GetAssetPath(type, name), GetAssetType(type))){if (callback != null)callback(Zeus.Framework.Asset.AssetManager.LoadAsset(GetAssetPath(type, name), GetAssetType(type)), param);}else{Zeus.Framework.Asset.AssetManager.LoadAssetAsync(GetAssetPath(type, name), GetAssetType(type), callback, param);}
#endif}

说明代码逻辑是先生成的窗口预制体然后,去缓存池中读上一次抽卡保存的结果,然后加载数据刷新面板。
所以现在是异步加载未完成然后就调用了后续的静态方法导致被迫中止。

4.问题解决

所以

HuanLingRewardController.ShowDrawResult(m_LastSpiritsLotteryPacket);

刷数据的逻辑应该放在ShowUI 执行成功的回调函数里。
于是,给方法新增标记,判断是否是第二次加载

HuanLingRewardController.ShowDrawResult(m_LastSpiritsLotteryPacket, false);

ShowUI.cs中

public static void ShowUI(SubPage defaultPage,bool isSecondEnter = false){// 针对绘卷UI进行特殊处理if (StoryScrollMainView.GetInstance()){StoryScrollMainView.GetInstance().NeedShowMenu = false;}if (StoryScrollSubView.GetInstance()){StoryScrollSubView.GetInstance().NeedShowMenu = false;}UIManager.ShowUI(UIInfo.HuanLingRoot, (isSuccess, _) =>{if (isSuccess && Instance){Instance.OnShow(defaultPage);}if (isSecondEnter){HuanLingRewardController.ShowDrawResult(m_LastSpiritsLotteryPacket, false);}});}

在UIManager.ShowUI 执行成功的回调中加入上述代码即可。
这样就保证了在界面预制体加载完成后,才会走刷数据的流程。
出现这样的问题也是因为,手机端异步加载资源的速度受到网络延迟,服务器结点的影响很大。用同步加载的逻辑去思考异步功能肯定是不行的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/504750.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第1篇 Linux Docker安装rabbitmq

Docker安装RabbitMq 1、搜索rabbitmq镜像 docker search rabbitmq2、下载rabbitmq镜像 docker pull rabbitmq3、运行rabbitmq服务 docker run -d --name rabbitmq --restart always -p 15672:15672 -p 5672:5672 rabbitmq4、访问rabbitmq http://192.168.1.x:15672 5、rab…

ISO_IEC_18598-2016自动化基础设施管理(AIM)系统国际标准解读(一)

██ ISO_IEC_18598-2016是什么标准&#xff1f; ISO/IEC 18598国际标准是由ISO&#xff08;国际标准化组织&#xff09;/IEC&#xff08;国际电工委员会&#xff09;联合技术委员会1-信息技术的第25分委员会-信息技术设备互连小组制定的关于信息基础设施自动化管理的国际标准&…

程序员是如何看待“祖传代码”的?

目录 ​编辑 程序员是如何看待“祖传代码”的&#xff1f; 一、什么是“祖传代码”&#xff1f; 二、“祖传代码”的利弊 1. 可以节省开发成本 2. 可能引入安全隐患 3. 可能增加系统的维护难度 三、祖传代对程序员的影响 1. 丰富程序员的技能和知识 2. 提高程序员的创…

Kubernetes/k8s的核心概念

一、什么是 Kubernetes Kubernetes&#xff0c;从官方网站上可以看到&#xff0c;它是一个工业级的容器编排平台。Kubernetes 这个单词是希腊语&#xff0c;它的中文翻译是“舵手”或者“飞行员”。在一些常见的资料中也会看到“ks”这个词&#xff0c;也就是“k8s”&#xff…

Linux shell中如何获取当前目录

Linux shell中获取当前目录 当前目录 每当你在终端进行操作时&#xff0c;你都会有一个当前工作目录。 使用pwd来判定当前目录在文件系统内的确切位置。 [rootlocalhost ~]# pwd /root在shell中也可以使用pwd来获取当前目录&#xff0c;并赋值给变量。 test.sh #!/bin/bas…

[linux] linux 常见信号以及使用信号时注意事项

信号是一种进程间通信的方式&#xff0c;进程间通信的方式还包括共享内存&#xff0c;socket&#xff0c;管道&#xff0c;消息队列。信号与其它方式是有区别的&#xff0c;其它通信方式很灵活&#xff0c;可以详细定义自己的消息内容&#xff1b;而信号没有这么灵活&#xff0…

7款炫酷的前端动画特效分享(二)(附效果图及在线演示)

分享7款好玩的前端动画特效 其中有CSS动画、SVG动画、js小游戏等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 jQuery拉开帷幕特效 基于jQuery实现的帷幕特效 点击右侧拉条 可以实现帷幕的收起也展开 非常的炫酷…

Doris实战——金融壹账通指标中台的应用实践

目录 前言 一、业务痛点 二、早期架构挑战 三、架构升级 四、一体化指标数据平台 4.1 构建指标体系 4.2 构建指标平台功能 五、Doris指标应用实践 六、未来规划 原文大佬的这篇指标中台的应用实践有借鉴意义&#xff0c;这里摘抄下来用作学习和知识沉淀。 前言 在搭建…

第四十七回 一丈青单捉王矮虎 宋公明二打祝家庄-强大而灵活的python装饰器

四面全是埋伏&#xff0c;宋江和众人一直绕圈跑不出去。正在慌乱之时&#xff0c;石秀及时赶到&#xff0c;教大家碰到白杨树就转弯走。走了一段时间&#xff0c;发现围的人越来越多&#xff0c;原来祝家庄以灯笼指挥号令。花荣一箭射下来红灯龙&#xff0c;伏兵自己就乱起来了…

【DAY07 软考中级备考笔记】数据结构:线性结构,数组矩阵和广义表

数据结构&#xff1a;线性结构&#xff0c;数组矩阵和广义表 3月2日 – 天气&#xff1a;晴 1. 线性表的定义和存储方式 > 这一部分只需要掌握下面的两点即可&#xff1a; > > * 采用顺序存储和链式存储的特点 > * 单链表的插入和删除操作 2. 栈和队列 > 这里需…

Godot自定义控件样式语法解析

前言 本篇原始文章写于2023年8月7日&#xff0c;存储在我的语雀文档中。但是语雀分享有诸多不便&#xff0c;为了让更多Godoter更轻松的搜到和看到&#xff0c;就转过来了。 这个项目我上传了Github&#xff0c;后续会贴上链接。 概述 Godot控件体系存在的问题之一就是样式无…

无人值守,24小时水质在线检测系统,助力信息化平台建设

水质在线监测系统主要由在线自动检测系统、通信网络和监控中心三部分组成&#xff0c;可以在无人值守的情况下自动完成水样的采集、水质分析、数据的采集和通信传输。 主要功能&#xff1a;监测水厂出口&#xff0c;输水管线和终端的水质情况。具体要求&#xff1a;地图显示。…