【真機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.pswp.cn/news/714803.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714803.shtml
英文地址,請注明出處:http://en.pswp.cn/news/714803.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++——模版

前言&#xff1a;哈嘍小伙伴們好久不見&#xff0c;這是2024年的第一篇博文&#xff0c;我們將繼續C的學習&#xff0c;今天這篇文章&#xff0c;我們來習一下——模版。 目錄 一.什么是模版 二.模版分類 1.函數模版 2.類模板 總結 一.什么是模版 說起模版&#xff0c;我們…

線索二叉樹

線索二叉樹即從前、中、后序三種遍歷中其中一種來看&#xff0c;樹中的左右孩子都不會是空著的&#xff0c;都會指向對應的前驅和后驅。 以中序遍歷為例&#xff0c;二叉樹線索化過程如下&#xff1a; 先是樹的結構 typedef struct ThreadNode{Elemetype data;struct ThreadNo…

微服務面試題之套路一

面試題 一、你的項目是從SpringBoot演進到微服務架構的&#xff0c;你在此過程中有調研過哪些技術&#xff0c;怎么調研落地的? 微服務通信框架&#xff1a; 需要選擇適合項目的微服務通信框架&#xff0c;如Dubbo、Spring Cloud或gRPC Feign RestTemplate 等。調研方式可以是…

高性能通信之Netty

一, 同步IO(BIO)模型的架構 一般針對性能不高的情況下可以使用. 二,異步IO(NIO)模型的架構 多路復用(epoll模型):

【LeetCode:124. 二叉樹中的最大路徑和 + 二叉樹+遞歸】

&#x1f680; 算法題 &#x1f680; &#x1f332; 算法刷題專欄 | 面試必備算法 | 面試高頻算法 &#x1f340; &#x1f332; 越難的東西,越要努力堅持&#xff0c;因為它具有很高的價值&#xff0c;算法就是這樣? &#x1f332; 作者簡介&#xff1a;碩風和煒&#xff0c;…

前端開發人員如何做好SEO

前端開發人員如何做好SEO SEO工作不僅限于專業人員。前端開發者也可以在日常開發中實施一些代碼層面的SEO優化。 以下是一些前端常用的SEO方法&#xff1a; 設置合理的title、keywords、description title、keywords、description對SEO至關重要&#xff0c;需貼合頁面內容編…

Codeforces Round 931 (Div. 2) (A~B)

比賽&#xff1a;Codeforces Round 931 (Div. 2) (A~B) 目錄&#xff1a;A B A題&#xff1a;Too Min Too Max 標簽: 構造算法&#xff08;constructive algorithms&#xff09;貪心&#xff08;greedy&#xff09;數學&#xff08;math&#xff09; 題目大意 對數組 a 找到…

【力扣hot100】刷題筆記Day19

前言 回溯回溯回溯&#xff01;早上整理檔案竟然用了桶排序&#xff0c;不愧是算法狂魔們 79. 單詞搜索 - 力扣&#xff08;LeetCode&#xff09; DFS class Solution:def exist(self, board: List[List[str]], word: str) -> bool:m, n len(board), len(board[0])# used…

mysql timestamp轉換為datetime

MySQL timestamp轉換為datetime的方法 1. 流程概述 在MySQL中&#xff0c;timestamp和datetime是兩種不同的數據類型。timestamp存儲了日期和時間&#xff0c;并且會自動更新&#xff0c;可以用于記錄數據的創建和修改時間。datetime則是一個固定的日期和時間&#xff0c;不會自…

談談高并發系統的設計方法論

談談高并發系統的設計方法論 何為高并發系統&#xff1f;什么是并發&#xff08;Conurrent&#xff09;&#xff1f;什么是高并發&#xff08;Hight Concurrnet&#xff09;&#xff1f;高并發的衡量指標有哪些&#xff1f; 實現高并發系統的兩大板塊高并發系統應用程序側的設計…

騰訊云學生服務器使用教程_申請騰訊云學生機詳細流程

2024年騰訊云學生服務器優惠活動「云校園」&#xff0c;學生服務器優惠價格&#xff1a;輕量應用服務器2核2G學生價30元3個月、58元6個月、112元一年&#xff0c;輕量應用服務器4核8G配置191.1元3個月、352.8元6個月、646.8元一年&#xff0c;CVM云服務器2核4G配置842.4元一年&…

還在用Jenkins?快來試試這款簡而輕的自動部署軟件!

最近發現了一個比 Jenkins 使用更簡單的項目構建和部署工具&#xff0c;完全可以滿足個人以及一些小企業的需求&#xff0c;分享一下。 Jpom 是一款 Java 開發的簡單輕量的低侵入式在線構建、自動部署、日常運維、項目監控軟件。 日常開發中&#xff0c;Jpom 可以解決下面這些…

Nginx的多線程支持探究

文章中心思想: Nginx本身并不直接支持多線程處理模型。它采用的是基于事件驅動的單線程或多進程架構,而非多線程模型。然而,通過Nginx的模塊和第三方擴展,可以實現類似多線程的并發處理效果。 詳細說明: Nginx,作為一款高性能的Web服務器和反向代理服務器,其架構和并發…

章節二、three.js開發入門與調試設置02;

一、軌道控制器查看物體&#xff1b; 1、基本概念 軌道控制器&#xff08;OrbitControls&#xff09;可以使得相機圍繞目標進行軌道運動&#xff1b; 2、代碼樣例 // 七、創建軌道控制器&#xff08;相機圍繞著物體捕捉視角&#xff09; const controls new OrbitControls(c…

吳恩達機器學習全課程筆記第五篇

目錄 前言 P80-P85 添加數據 遷移學習 機器學習項目的完整周期 公平、偏見與倫理 P86-P95 傾斜數據集的誤差指標 決策樹模型 測量純度 選擇拆分方式增益 使用分類特征的一種獨熱編碼 連續的有價值特征 回歸樹 前言 這是吳恩達機器學習筆記的第五篇&#xff0c…

《2023跨境電商投訴大數據報告》發布|亞馬遜 天貓國際 考拉海購 敦煌網 阿里巴巴

2023年&#xff0c;跨境電商API接口天貓國際、京東國際和抖音全球購以其強大的品牌影響力和市場占有率&#xff0c;穩坐行業前三的位置。同時&#xff0c;各大跨境電商平臺消費糾紛問題層出不窮。依據國內知名網絡消費糾紛調解平臺“電訴寶”&#xff08;315.100EC.CN&#xff…

javaEE--后端環境變量配置

目錄 pre 文件準備 最終運行成功結果 后端運行步驟 1.修改setenv文件 2.運行setenv&#xff0c;設置環境變量 3.查看jdk版本 4.修改mysql文件夾下的my文件 前端運行步驟 1.nodejs環境配置 2.查看node和npm版本 3.下載并運行npm 4.注冊登錄 pre 文件準備 最終運行…

VR轉接器:破解虛擬與現實邊界的革命性設備

VR轉接器&#xff0c;這一革命性的設備&#xff0c;為虛擬現實體驗帶來了前所未有的自由度。它巧妙地連接了虛擬與現實&#xff0c;使得用戶在享受VR眼鏡帶來的奇幻世界的同時&#xff0c;也能自由地在現實世界中活動。這一設計的誕生&#xff0c;不僅解決了VR眼鏡續航的瓶頸問…

2、云原生安全之可視化界面rancher的部署

文章目錄 1、rancher的部署1.1、安裝rancher1.2、配置k8s2、部署helm3、容器安全工具neuvector此時已經部署好了k8s,使用rancher來管理 rancher簡化了使用k8s的流程,可以圖形化管理k8s。 參考: https://blog.51cto.com/u_15343792/5000311https://docs.rancher.cn/docs/ra…

你們團隊是否有RocketMQ創建Topic、GID創建規范呢

這里是weihubeats,覺得文章不錯可以關注公眾號小奏技術 背景 早期在使用RocketMQ的時候&#xff0c;系統和開發人員不算多。所以topic的創建會非常隨意&#xff0c;各種千奇百怪的topic 比如: order_topic、ORDER_TOPIC、order-topic 各種奇奇怪怪的風格&#xff0c;用_的&a…