HarmonyOS應用開發之界面列表不刷新問題Bug排查記:從現象到解決完整記錄

Bug排查在軟件開發過程中扮演著至關重要的角色,本文采用日記形式記錄了Bug排查的全過程,通過這種方式可以更加真實、詳細地記錄問題,便于后續追溯和經驗沉淀。

Bug背景

在使用HarmonyOS的ArkUI框架開發一個卡片管理應用時,遇到了List列表界面不刷新的問題。具體表現為,雖然數據已經更新,但界面并未同步刷新顯示。比如在子頁面中明明添加了卡片并更新了數據,但是頁面返回后,看到的卡片數量并未發生變化。

在這里插入圖片描述

環境

  • 設備:HarmonyOS模擬器
  • 系統版本:HarmonyOS 5.0
  • 應用框架:ArkUI

復現條件

在多個界面的狀態共享時,使用了@Provider@Consumer裝飾器,同時對類和成員變量使用了@ObservedV2@Trace裝飾,從而實現了數據的共享和追蹤。在添加、刪除或更新卡片數據時,數據操作成功,但List列表并未刷新顯示最新的數據。

在這里插入圖片描述

這一行就是問題所在。之前的 uid 一直是同一個。。。,結果導致數據變化,UI不會觸發刷新。
之前這里的寫法如下:

 ForEach(this.cardViewModel?.cardDeckList ?? [], (item: CardDeckData,index) => {Row() {CardDeck({})}}, (item: CardDeckData) => item.uid)

問題出在這個ForEach循環的最后一個參數item.uid上。

坑一:ForEach循環的key生成器

在使用ForEach循環渲染列表時,注意到最后一個參數——key生成器。這個參數用于生成列表項的唯一標識,如果設置不當,就可能導致列表項無法正確更新。

問題

數據已經更新,但通過ForEach循環渲染的列表界面并未刷新顯示最新的數據。

分析與假設

分析關鍵代碼片段,發現ForEach循環的key生成器僅使用了item.id,這樣雖然可以保證唯一性,但當數據發生變化時,key并未隨之更新,導致界面無法刷新。

解決方案

通過修改key生成器的邏輯,將item.id與更新的成員變量的值進行組合,確保當數據變化時,key也會隨之變化,從而實現界面的正確刷新。

在這里插入圖片描述

修復代碼具體改動
ForEach(this.cardViewModel?.cardDeckList ?? [], (item: CardDeckData,index) => {}, (item: CardDeckData) => item.uid + '_' + JSON.stringify(item))

要保證數據更新后,不但這個key是唯一的,且是變化了的。

測試驗證

修改代碼后,進行了單元測試和集成測試,確認問題已解決。

坑二:列表數組中元素值改變界面不刷新

再次遇到數據不刷新的問題,通過調試發現需要對cardDeckList進行重新賦值才能刷新界面。
在這里插入圖片描述

//  viewmodol/cardViewModol.ets
import DBDeckApi from "../common/api/deckApi";
import { TBCardDeckEntity } from "../model/TBCardDeck";
import { getCurrentDateTime } from "../utils/dateUtil";
import { Log } from "../utils/logutil";
import { ToastUtil } from "../utils/ToastUtil";@ObservedV2
export class CardDeckData{@Trace uid: number | undefined = 0@Trace name: string| undefined='';@Trace desc: string| undefined = ''// 卡片張數@Trace cardNum: number | undefined = 0// 已學習張數@Trace readNum: number | undefined = 0// 學習時長@Trace timeLen: number | undefined = 0// 創建時間@Trace createTime: string | undefined = ''// 更新時間@Trace updateTime: string | undefined = ''// 開始學習時間@Trace startTime: string | undefined = ''// 結束學習時間@Trace endTime: string | undefined = ''
}@ObservedV2
export class CardViewModel {private static instance: CardViewModel | null = null;@Trace cardDeckList: CardDeckData[] = []static getInstance(): CardViewModel {if (!CardViewModel.instance) {CardViewModel.instance = new CardViewModel();}return CardViewModel.instance;}/*** 添加卡組* @param timelineId 時光軸ID*/addCardDeck(name:string, desc:string) {const rec = new TBCardDeckEntity()rec.name = namerec.desc = descrec.createTime = getCurrentDateTime()DBDeckApi.insertCardDeck(rec).then((number) => {if (number < 0) {Log.error("insertCardDeck error,code=%{public}d", number)ToastUtil.showError("添加失敗")} else {Log.debug("insertCardDeck ok,code=%{public}d", number)this.reloadDeckDbData()ToastUtil.showSuccess("添加成功")}})}/*** 從數據庫從新加載卡組數據列表*/reloadDeckDbData(){//從數據庫獲取數據DBDeckApi.queryAllCardDeck().then((result) => {Log.debug(result?.length)this.cardDeckList = result ?? [];const newList = [...this.cardDeckList];this.cardDeckList = newList;// 生成新數組,確保元素為全新實例//const newList = result?.map(item => ({ ...item })) ?? [];/*this.cardDeckList = result?.map(item => ({uid: item.uid ?? 0,name: item.name ?? '',desc: item.desc ?? '',cardNum: item.cardNum,readNum: item.readNum,createTime: item.createTime,updateTime: item.updateTime,startTime: item.startTime,endTime: item.endTime} as CardDeckData)) ?? [];* *//*this.cardDeckList = result?.map(entity => {const data = new CardDeckData();// 顯式屬性映射(示例)data.uid = entity.uid ?? undefined;data.name = entity.name ?? ''; // 處理 undefined 轉空字符串data.desc = entity.desc ?? '';data.cardNum = entity.cardNum ?? 0;data.readNum = entity.readNum ?? 0;data.createTime = entity.createTime!;data.updateTime = entity.updateTime!;return data;})?? [];* */})}

問題

在添加、刪除或更新卡片數據后,雖然數據已經變化,但List列表并未刷新顯示最新的數據。
必須:非得這么紅框里再次賦值才可以刷新啊。顯得很低效,但也很無奈。說好的@ObservedV2和@Trace裝飾類和成員變量,怎么沒觀察到成員變量的變化呢?

分析與假設

reloadDeckDbData方法中,直接將數據庫查詢到的數據賦值給cardDeckList,但由于賦值的對象引用沒有變化,導致界面未能檢測到數據變化。

解決方案

通過重新生成一個新的數組,并將查詢到的數據賦值給新的數組,然后再將新的數組賦值給cardDeckList,這樣可以確保對象引用發生變化,從而實現界面的正確刷新。

修復代碼具體改動
DBDeckApi.queryAllCardDeck().then((result) => {Log.debug(result?.length)this.cardDeckList = result ?? [];const newList = [...this.cardDeckList];this.cardDeckList = newList;
})

測試驗證

修改代碼后,進行了單元測試和集成測試,確認問題已解決。

影響范圍

  • 功能模塊:卡片管理模塊
  • 用戶體驗:用戶無法看到最新的卡片數量,影響操作感受
  • 業務邏輯:無法準確顯示業務數據,影響應用功能

經驗總結

技術收獲

  • 使用@ObservedV2@Trace裝飾類和成員變量,可以方便地追蹤和處理數據變化。
  • ForEach循環的key生成器必須能夠正確地反映數據變化,從而保證界面的正確刷新。
  • 重新賦值對象以改變其引用,可以確保界面能夠正確檢測到數據變化并進行刷新。

流程優化

  • 使用代碼審查(Code Review)和測試策略可以避免類似的問題。
  • 在開發過程中,應充分考慮框架特性和代碼邏輯,避免不必要的“坑”。
  • 通過調試器和日志分析工具等工具,可以快速定位問題并進行修復。

附錄

相關技術文檔鏈接

  • ArkUI ForEach文檔
  • HarmonyOS數據共享文檔

參考工具清單

  • HarmonyOS調試器
  • Log分析工具(如Logcat)
  • Sentry(錯誤監控系統)

通過以上記錄,希望能夠幫助其他開發者避免在使用ArkUI時遇到類似的問題,同時也為提升自身的代碼質量和開發效率提供了一定的參考。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/95535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/95535.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/95535.shtml

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

相關文章

FastVLM-0.5B 模型解析

模型介紹 FastVLM&#xff08;Fast Vision-Language Model&#xff09;是蘋果團隊于2025年在CVPR會議上提出的高效視覺語言模型&#xff0c;專為移動設備&#xff08;如iPhone、iPad、Mac&#xff09;優化&#xff0c;核心創新在于通過全新設計的 FastViTHD混合視覺編碼器 解決…

集成學習 | MATLAB基于CNN-LSTM-Adaboost多輸入單輸出回歸預測

集成學習 | MATLAB基于CNN-LSTM-Adaboost多輸入單輸出回歸預測 一、主要功能 該代碼使用 CNN 提取特征,LSTM 捕捉時序依賴,并通過 AdaBoost 集成多個弱學習器(每個弱學習器是一個 CNN-LSTM 網絡),最終組合成一個強預測器,用于回歸預測任務。代碼完成了從數據預處理、模型…

關于Homebrew:Mac快速安裝Homebrew

關于macOS 安裝HomebrewHomebrewHomebrew介紹Homebrew 官網地址Homebrew 能安裝什么&#xff1f;Mac上安裝Homebrew主要步驟&#xff1a;打開終端&#xff0c;執行官網安裝腳本注意遇到問題①&#xff1a;腳本在克隆 Homebrew 核心倉庫時&#xff0c;??無法連接 GitHub??&a…

【前端】使用Vercel部署前端項目,api轉發到后端服務器

文章目錄Vercel是什么概要Vercel部署分為兩種方案&#xff1a;一、使用GitHub構建部署二、通過 Vercel CLI 上傳本地構建資源注意事項轉發API到后端小結Vercel是什么 Vercel是一款專為前端開發者打造的云部署平臺&#xff0c;它支持一鍵部署靜態網站、AI工具和現代Web應用。Ve…

滾珠導軌在工業制造領域如何實現高效運行?

在工業制造領域中滾珠導軌憑借其高精度、低摩擦、高剛性等特點&#xff0c;被廣泛應用于多種設備和場景&#xff0c;并在設備性能中起著關鍵作用&#xff0c;以下是具體應用&#xff1a;加工中心&#xff1a;滾珠導軌用于加工中心的工作臺和主軸箱等部件的移動&#xff0c;能保…

大基座模型與 Scaling Law:AI 時代的邏輯與困境

一、背景&#xff1a;為什么大模型一定要“做大”&#xff1f; 在人工智能的發展歷程中&#xff0c;有一個不容忽視的“鐵律”&#xff1a;更大的模型往往意味著更強的性能。從 GPT-2 到 GPT-4&#xff0c;從 BERT 到 PaLM&#xff0c;從 LLaMA 到 Claude&#xff0c;每一代的…

內網的應用系統間通信需要HTTPS嗎

內網是否需要 HTTPS&#xff1f; 雖然內網通常被視為“相對安全”的環境&#xff0c;但仍需根據具體情況決定是否使用 HTTPS&#xff0c;原因如下&#xff1a; 內部威脅風險 ● 內網可能面臨內部人員攻擊、橫向滲透&#xff08;如黑客突破邊界后在內網掃描&#xff09;、設備…

6.ImGui-顏色(色板)

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 本次游戲沒法給 內容參考于&#xff1a;微塵網絡安全 上一個內容&#xff1a;5.ImGui-按鈕 IMGui中表示顏色的的結構體 ImVec4和ImU32&#xff0c;如下圖紅框…

【C++】Vector完全指南:動態數組高效使用

0. 官方文檔 vector 1. vector介紹 Vector 簡單來說就是順序表&#xff0c;是一個可以動態增長的數組。 vector是表示可變大小數組的序列容器。 就像數組一樣&#xff0c;vector也采用的連續存儲空間來存儲元素。也就是意味著可以采用下標對vector的元素進行訪問&#xff0c…

關于無法導入父路徑的問題

問題重現 有下面的代碼&#xff1a; from ..utils import Config,set_DATA_PATH DATA_PATH set_DATA_PATH()報錯如下&#xff1a;from ..utils import Config,set_DATA_PATH ImportError: attempted relative import beyond top-level package解決方案 #獲取當前腳本所在目錄的…

C/C++包管理工具:Conan

Conan是一個專為C/C設計的開源、去中心化、跨平臺的包管理器&#xff0c;致力于簡化依賴管理和二進制分發流程。Conan基于Python進行開發&#xff0c;支持與主流的構建系統集成&#xff0c;提供了強大的跨平臺和交叉編譯能力。通過Conan&#xff0c;開發者可以高效的創建、共享…

核心高并發復雜接口重構方案

核心高并發復雜接口重構方案 一、重構目標與原則 核心目標 提升接口性能:降低響應時間,提高吞吐量,降低資源使用 增強可維護性:拆解復雜邏輯,模塊化設計,降低后續迭代成本 保障穩定性:通過架構優化和灰度策略,確保重構過程無服務中斷 提升擴展性:設計靈活的擴展點,…

C++容器內存布局與性能優化指南

C容器的內存布局和緩存友好性對程序性能有決定性影響。理解這些底層機制&#xff0c;能幫你寫出更高效的代碼。 一、容器內存布局概述 不同容器在內存中的組織方式差異顯著&#xff0c;這直接影響了它們的訪問效率和適用場景。容器類型內存布局特點元數據位置元素存儲位置std::…

Beautiful.ai:AI輔助PPT工具高效搞定排版,告別熬夜做匯報煩惱

你是不是每次做 PPT 都頭大&#xff1f;找模板、調排版、湊內容&#xff0c;熬大半夜出來的東西還沒眼看&#xff1f;尤其是遇到 “明天就要交匯報” 的緊急情況&#xff0c;打開 PPT 軟件半天&#xff0c;光標在空白頁上晃來晃去&#xff0c;連標題都想不出來 —— 這種抓瞎的…

阿里云攜手MiniMax構建云原生數倉最佳實踐:大模型時代的 Data + AI 數據處理平臺

MiniMax簡介MiniMax是全球領先的通用人工智能科技公司。自2022年初成立以來&#xff0c;MiniMax以“與所有人共創智能”為使命&#xff0c;致力于推動人工智能科技前沿發展&#xff0c;實現通用人工智能(AGI&#xff09;。MiniMax自主研發了一系列多模態通用大模型&#xff0c;…

一鍵生成PPT的AI工具排名:2025年能讀懂你思路的AI演示工具

人工智能正在重塑PPT制作方式&#xff0c;讓專業演示變得觸手可及。隨著人工智能技術的飛速發展&#xff0c;AI生成PPT工具已成為職場人士、學生和創作者提升效率的得力助手。這些工具通過智能算法&#xff0c;能夠快速將文本、數據或創意轉化為結構化、視覺化的演示文稿&#…

數據庫基礎知識——聚合函數、分組查詢

目錄 一、聚合函數 1.1 count 1.1.1 統計整張表中所有記錄的總條數 1.1.2 統計單列的數據 1.1.3 統計單列記錄限制條件 1.2 sum 1.3 avg 1.4 max, min 二、group by 分組查詢 2.1 語法 2.2 示例 2.3 having 一、聚合函數 常用的聚合函數 函數說明count ([distinc…

改 TDengine 數據庫的時間寫入限制

一 sql連數據庫改 改 TDengine 數據庫的時間寫入限制 之前默認了可寫入時間為一個月&#xff0c;調整為10年&#xff0c;方便測試&#xff1a; SHOW DATABASES;use wi; SELECT CONCAT(ALTER TABLE , table_name, KEEP 3650;) FROM information_schema.ins_tables WHERE db_…

數碼視訊TR100-OTT-G1_國科GK6323_安卓9_廣東聯通原機修改-TTL燒錄包-可救磚

數碼視訊TR100-OTT-G1_國科GK6323_安卓9_廣東聯通原機修改-TTL燒錄包-可救磚刷機教程數碼視訊 TR100-G1 TTL 燒錄刷機教程固件由廣東聯通 TR100-G1 28 原版修改&#xff0c;測試一切正常1、把刷機文件解壓出 備用&#xff0c;盒子主板接好 TTL&#xff0c;不會接自行查找 TTl 接…

TVS防護靜電二極管選型需要注意哪些參數?-ASIM阿賽姆

TVS防護靜電二極管選型關鍵參數詳解TVS(Transient Voltage Suppressor)二極管作為電路防護的核心器件&#xff0c;在電子設備靜電防護(ESD)、浪涌保護等領域發揮著重要作用。本文將系統性地介紹TVS二極管選型過程中需要重點關注的參數指標&#xff0c;幫助工程師做出合理選擇。…