【HarmonyOS Next】鴻蒙應用故障處理思路詳解

【HarmonyOS Next】鴻蒙應用崩潰處理思路詳解

一、崩潰問題發現后定位

1. 崩潰現象:
常見的崩潰問題表現為,應用操作后白屏閃退,或者應用顯示無響應卡死。

2.定位問題:
發現崩潰后,我們首先需要了解復現步驟,精確定位復現步驟。因為提供復現步驟得人,可能是用戶和測試,非開發人員,其中的步驟并非最短路徑。

3.排查問題點
根據復現步驟,我們需要查看日志表現,鴻蒙的DevEco IDE提供了日志看板,根據HiLog和FaultLog,我們可以初步區分崩潰問題的類型。
在這里插入圖片描述
根據日志看板的FaultLog,可以查看崩潰輸出的

  1. JS Crash,一般是ArkTS原生邏輯的崩潰
  2. CppCrash,一般是NDK,C層的崩潰

JS Crash
點擊進入JS Crash中,可以查看到崩潰信息,以下幾種類型的錯誤:
在這里插入圖片描述
可以根據JS Crash提示的錯誤行數,直接點擊跳轉到錯誤代碼處,根據提示檢查和修復問題。

Device info:xxx
Build info:xxx-xxx x.x.x.xxx(xxxx)
Fingerprint:a370fceb59011d96e41e97bda139b1851c911012ab8c386d1a2d63986d6d226d
Module name:com.xxx.xxX
Version:1.0.0
Versioncode:1000000
PreInstalled:No
Foreground:Yes
Pid:39185Uid:20020145
Reason:TypeError
Error name:TypeError
Error message:Cannot read property needRenderTranslate of undefined
Stacktrace:Cannot get SourceMap info, dump raw stack:at anonymous (entry/src/main/ets/pages/Index.ts:49:49)

在這里插入圖片描述

this.translationUpY = (this,multiCardsNum >= 1)? sceneContainerSessionListlthis.multiCardsNum -1].needRenderTranslate.translateY :0
this.translationDownY = (this.multiCardsNum >= 2)? sceneContainerSessionList[this.multiCardsNum -
2].needRenderTranslate.translateY :0;

CppCrash
根據日志提示,檢查是否有以下錯誤情況:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

AppFreeze
一般是由于耗時操作,導致堵塞主線程。此時用戶操作時,會觸發無響應。一般分為以下三種情況,超時時間一般在6s左右。
在這里插入圖片描述

內存泄漏
這種問題排查起來是最麻煩的,所以保持良好的代碼編程規范,不需要的對象該釋放釋放,不用的句柄也需要釋放。

一般碰到內存泄漏,根據提供的復現步驟,很多情況下是非必現。(如果是必現,那最好了,修復該問題會很快。)我們需要操作復現步驟,使用鴻蒙DevEco IDE的ProFiler工具:
在這里插入圖片描述
檢測應用操作時的內存使用情況。
在這里插入圖片描述

二、問題解決,檢查類似錯誤情況一起修復

1.根據章節一問題定位清楚后,根據錯誤具體情況,思考修復方案

2.根據問題情況,檢查其他代碼是否有同類問題,一起修復后驗證。

3.根據官網提供的材料進行學習,編碼過程中進行規范和排查:
在這里插入圖片描述

性能優化舉例:
業務場景是:點擊跳轉下一頁,直接加載Web頁面。這是大多數三方應用的實現方式,其實應該在后臺創建一個ArkWeb組件來預先啟動用于渲染的Web渲染進程。這樣跳轉到web頁面的時間就不會那么長:

// 創建NodeController
// common.ets
import { UIContext } from '@kit.ArkUI';
import { webview } from '@kit.ArkWeb';
import { NodeController, BuilderNode, Size, FrameNode } from '@kit.ArkUI';// @Builder中為動態組件的具體組件內容
// Data為入參封裝類
class Data {url: string = 'https://www.example.com';controller: WebviewController = new webview.WebviewController();
}
function webBuilder(data: Data) {Column() {Web({ src: data.url, controller: data.controller }).domStorageAccess(true).zoomAccess(true).fileAccess(true).mixedMode(MixedMode.All).width('100%').height('100%').onPageEnd((event) => {// 輸出Web頁面加載完成時間console.info(`load page end time: ${Date.now()}`);})}
}let wrap = wrapBuilder<Data[]>(webBuilder);// 用于控制和反饋對應的NodeContainer上的節點的行為,需要與NodeContainer一起使用
export class MyNodeController extends NodeController {private rootnode: BuilderNode<Data[]> | null = null;private root: FrameNode | null = null;private rootWebviewController: webview.WebviewController | null = null;// 必須要重寫的方法,用于構建節點數、返回節點掛載在對應NodeContainer中// 在對應NodeContainer創建的時候調用、或者通過rebuild方法調用刷新makeNode(uiContext: UIContext): FrameNode | null {console.info(' uicontext is undefined : ' + (uiContext === undefined));if (this.rootnode != null) {const parent = this.rootnode.getFrameNode()?.getParent();if (parent) {console.info(JSON.stringify(parent.getInspectorInfo()));parent.removeChild(this.rootnode.getFrameNode());this.root = null;}this.root = new FrameNode(uiContext);this.root.appendChild(this.rootnode.getFrameNode());// 返回FrameNode節點return this.root;}// 返回null控制動態組件脫離綁定節點return null;}// 當布局大小發生變化時進行回調aboutToResize(size: Size) {console.info('aboutToResize width : ' + size.width + ' height : ' + size.height);}// 當controller對應的NodeContainer在Appear的時候進行回調aboutToAppear() {console.info('aboutToAppear');}// 當controller對應的NodeContainer在Disappear的時候進行回調aboutToDisappear() {console.info('aboutToDisappear');}// 此函數為自定義函數,可作為初始化函數使用// 通過UIContext初始化BuilderNode,再通過BuilderNode中的build接口初始化@Builder中的內容initWeb(url: string, uiContext: UIContext, control: WebviewController) {if (this.rootnode != null) {return;}// 綁定預創建的WebviewControllerthis.rootWebviewController = control;// 創建節點,需要uiContextthis.rootnode = new BuilderNode(uiContext);// 創建動態Web組件this.rootnode.build(wrap, { url: url, controller: control });}// 此函數為自定義函數,可作為初始化函數使用loadUrl(url: string) {if (this.rootWebviewController !== null) {// 復用預創建組件,重新加載urlthis.rootWebviewController.loadUrl(url);}}
}// 創建Map保存所需要的NodeController
let NodeMap: Map<string, MyNodeController | undefined> = new Map();
// 創建Map保存所需要的WebViewController
let controllerMap: Map<string, WebviewController | undefined> = new Map();// 初始化需要UIContext 需在Ability獲取
export const createNWeb = (url: string, uiContext: UIContext) => {// 創建NodeControllerlet baseNode = new MyNodeController();let controller = new webview.WebviewController();// 初始化自定義web組件baseNode.initWeb(url, uiContext, controller);controllerMap.set(url, controller);NodeMap.set(url, baseNode);
};// 自定義獲取NodeController接口
export const getNWeb = (url: string): MyNodeController | undefined => {// 加載新的Url時,建議復用預創建的Web組件if (!NodeMap.get(url) && NodeMap.get('about://blank')) {// 獲取預創建的Web組件let webNode = NodeMap.get('about://blank') as MyNodeController;// 重新加載urlwebNode.loadUrl(url);return webNode;}return NodeMap.get(url);
};

三、思考如何避免問題再次發生,復盤

1.保持好的開發習慣創建踩坑文檔,避免自己第二次再發生該問題

2.根據錯誤情況,分析是否為自己代碼邏輯問題,邏輯bug不可避免,只能從開發經驗和code review中盡量避免

3.代碼容錯分支問題,只保證了主流程,未考慮代碼錯誤分支的覆蓋情況。這種情況,需要自己吸取教訓,避免再次發生。

4.使用檢測工具對代碼進行掃描,提前規避一些問題:
在這里插入圖片描述
5.使用IDE提供的AppAnglyzer生成應用檢測報告。根據報告提示,進行修改:
在這里插入圖片描述
6.使用鴻蒙提供的DevEco Testing工具,進行穩定性和功耗等測試:
在這里插入圖片描述

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

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

相關文章

linunx ubuntu24.04.02裝libfuse2導致無法開機進不了桌面解決辦法

osu.appimage運行需要libfuse2 然后我就下了fuse,打了兩把第二天無法開機 這樣是不能開機的 這樣是可以開機的 解決辦法一&#xff1a;玩星火商店的osu&#xff0c;好了問題解決 解決辦法二&#xff1a; 在這個頁面 ctrl alt f2進入tty6 sudo apt install ubuntu-desktop 進…

Maven 的常用指令

一、核心構建指令 mvn clean 作用&#xff1a;刪除 target 目錄&#xff08;清理編譯/打包生成的文件&#xff09;。 場景&#xff1a;確保從頭開始構建&#xff0c;避免殘留文件干擾。 mvn compile 作用&#xff1a;編譯項目源代碼。 場景&#xff1a;快速檢查代碼是否能編…

llvm數據流分析

llvm數據流分析 1.數據流分析2.LLVM實現2.1.常量傳播2.2.活躍性分析 相關參考文檔&#xff1a;DataFlowAnalysisIntro、ustc編譯原理課程、南大程序分析課程1、南大程序分析課程2。 1.數據流分析 數據流分析在編譯優化等程序分析任務上都有重要應用。通常數據流分析可被抽象為…

C++ MySQL 常用接口(基于 MySQL Connector/C++)

C MySQL 常用接口&#xff08;基于 MySQL Connector/C&#xff09; 1. 數據庫連接 接口&#xff1a; sql::mysql::MySQL_Driver *driver; sql::Connection *con;作用&#xff1a; 用于創建 MySQL 連接對象。 示例&#xff1a; driver sql::mysql::get_mysql_driver_insta…

C++藍橋杯基礎篇(十一)

片頭 嗨~小伙伴們&#xff0c;大家好&#xff01;今天我們來學習C藍橋杯基礎篇&#xff08;十一&#xff09;&#xff0c;學習類&#xff0c;結構體&#xff0c;指針相關知識&#xff0c;準備好了嗎&#xff1f;咱們開始咯~ 一、類與結構體 類的定義&#xff1a;在C中&#x…

css中實現border距離視圖左右兩側有距離

首先看效果圖 再看css是如何實現 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>.main {background-color: aqua;display: block;width: 300px;padding: 0px 32px;box-sizing: border-box;}/…

Ubuntu 22.04 無法進入圖形界面的解決方法

Ubuntu 22.04 無法進入圖形界面&#xff0c;只能進入 tty&#xff0c;可能是由于圖形界面相關的配置或驅動程序出現了問題。以下是一些常見的解決方法&#xff1a; 1. 檢查圖形界面服務狀態 首先&#xff0c;檢查圖形界面服務&#xff08;通常是 gdm 或 lightdm&#xff09;的…

Tweak Power:全方位電腦系統優化的高效工具

在日常使用電腦時&#xff0c;系統性能的下降、垃圾文件的堆積以及硬盤的老化等問題常常困擾著用戶。為了提升電腦性能、優化系統運行&#xff0c;許多人會選擇系統優化工具。然而&#xff0c;國內一些系統優化軟件常常因為廣告過多或功能冗雜而讓人望而卻步。此時&#xff0c;…

深入淺出Bearer Token:解析工作原理及其在Vue、Uni-app與Java中的實現Demo

目錄 前言1. 基本知識2. Demo3. 實戰 前言 &#x1f91f; 找工作&#xff0c;來萬碼優才&#xff1a;&#x1f449; #小程序://萬碼優才/r6rqmzDaXpYkJZF 1. 基本知識 Bearer Token是一種基于Token的認證機制&#xff0c;用于在HTTP請求中傳遞用戶的身份信息 應用于RESTful A…

kubernetes——part3-5 核心概念 Service

一、 service作用 使用kubernetes集群運行工作負載時&#xff0c;由于Pod經常處于用后即焚狀態&#xff0c;Pod經常被重新生成&#xff0c;因此Pod對應的IP地址也會經常變化&#xff0c;導致無法直接訪問Pod提供的服務&#xff0c;Kubernetes中使用了Service來解決這一問題&am…

從零開始 | C語言基礎刷題DAY1

?個人主頁&#xff1a;折枝寄北的博客 DAY1[2025.3.11] 1. 求兩個數的較大值2.從鍵盤輸入的兩個數的大小關系3.一個整數的奇偶性&#xff0c;請判斷4. 考試分數是否通過5.考試成績是否完美&#xff0c;請判斷 1. 求兩個數的較大值 題目&#xff1a; 寫一個函數求兩個整數的較…

開源模型時代的 AI 開發革命:Dify 技術深度解析

開源模型時代的AI開發革命&#xff1a;Dify技術深度解析 引言&#xff1a;AI開發的開源新紀元 在生成式AI技術突飛猛進的2025年&#xff0c;開源模型正成為推動行業創新的核心力量。據統計&#xff0c;全球超過80%的AI開發者正在使用開源模型構建應用&#xff0c;這一趨勢不僅…

Dify Web 前端獨立部署指南(與后端分離,獨立部署)

背景:單獨拆分前端出來部署,二開前后端 本文檔專注于 Dify Web 前端的部署流程和配置,適用于需要將項目部署到各種環境的運維人員和開發者。 1. 環境準備 1.1 部署環境要求 Node.js >= 18.17.0Nginx 或其他Web服務器(生產環境推薦)Docker(可選,用于容器化部署)1.…

《蒼穹外賣》SpringBoot后端開發項目核心知識點整理(DAY1 to DAY3)

目錄 一、在本地部署并啟動Nginx服務1. 解壓Nginx壓縮包2. 啟動Nginx服務3. 驗證Nginx是否啟動成功&#xff1a; 二、導入接口文檔1. 黑馬程序員提供的YApi平臺2. YApi Pro平臺3. 推薦工具&#xff1a;Apifox 三、Swagger1. 常用注解1.1 Api與ApiModel1.2 ApiModelProperty與Ap…

大數據hadoop課程筆記

1.課程導入 柯潔 Alpha Go是人工智能領域的里程碑。 深度學習 大模型deepseek chatgpt 大模型 和 大數據 之間有著非常緊密的關系。可以說&#xff0c;大數據是大模型發展的基石&#xff0c;而大模型是大數據價值挖掘的重要工具。 https://youtu.be/nN-VacxHUH8?sifj7Ltk…

架構學習第八周--Kubernetes博客搭建

目錄 一、整體架構 二、部署MySQL主從 三、部署Redis哨兵 四、部署WordPress 五、注意事項 一、整體架構 本項目為在一主三從的Kubernetes集群上部署WordPress博客。因為WordPress部分容器版本自行集成Apache和PHP服務&#xff0c;因此在Kubernetes上部署WordPress只需提供…

Application.OnTime如何引用帶參數的過程

Application.OnTime方法本身并不直接支持傳遞參數給被調用的過程。不過&#xff0c;有幾種方法可以間接實現這個需求。 方法1&#xff1a;使用單引號表達式 使用單引號表達式來傳遞參數時&#xff0c;不能在表達式中使用變量&#xff0c;需要把參數值直接寫到表達中&am…

網絡安全之tcpdump工具

引言 wireshark是一款非常不錯的抓包軟件&#xff0c;在圖形化界面占絕對統治地位&#xff1b;盡管其在字符界面下有些許選項可供使用&#xff0c;但終究不太方便&#xff0c;下面我再介紹一款NB的終端抓包工具 tcpdump 1、混雜模式 linux的網卡有混雜模式一說&#xff0c;當開…

VC++ 獲取目的IP的路由

GetBestRoute 函數獲取到目的IP的最佳匹配路由。 第一個參數為&#xff1a;destination&#xff08;目的IP&#xff09; 第二個參數為&#xff1a;source&#xff08;源IP&#xff09; 通常不需要指定第二個source&#xff0c;這個一般用來匹配具體某一個網卡接口路由的&…

JavaScript 模塊 vs C# 類:封裝邏輯的兩種哲學

引言 在現代軟件開發中&#xff0c;模塊化和面向對象設計是代碼組織的核心課題。本文通過對比 JavaScript 模塊&#xff08;ES6 Module&#xff09;與 C# 類&#xff08;Class&#xff09;的實現方式&#xff0c;探討兩種語言在封裝邏輯時的不同哲學&#xff0c;并給出實際應用…