国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

逐個分析鴻蒙內核七段追蹤代碼

鴻蒙系統HarmonyOS ? 來源:my.oschina ? 作者:鴻蒙內核源碼分析 ? 2021-04-28 16:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本篇通過一張圖和七段代碼詳細說明系統調用的整個過程,代碼一捅到底,直到匯編層再也捅不下去. 先看圖,這里的模式可以理解為空間,因為模式不同運行的棧空間就不一樣.

pIYBAGCJIQ-ANIgUAACYJqdJ9_0363.png

過程解讀

在應用層main中使用系統調用mq_open(posix標準接口)

mq_open被封裝在庫中,這里直接看庫里的代碼.

mq_open中調用syscall,將參數傳給寄出器R7,R0~R6

SVC 0完成用戶模式到內核模式(SVC)的切換

_osExceptSwiHdl運行在svc模式下.

PC寄存器直接指向_osExceptSwiHdl處取指令.

_osExceptSwiHdl是匯編代碼,先保存用戶模式現場(R0~R12寄存器),并調用OsArmA32SyscallHandle完成系統調用

OsArmA32SyscallHandle中通過系統調用號(保存在R7寄存器)查詢對應的注冊函數SYS_mq_open

SYS_mq_open是本次系統調用的實現函數,完成后return回到OsArmA32SyscallHandle

OsArmA32SyscallHandle再return回到_osExceptSwiHdl

_osExceptSwiHdl恢復用戶模式現場(R0~R12寄存器)

從內核模式(SVC)切回到用戶模式,PC寄存器也切回用戶現場.

由此完成整個系統調用全過程

七段追蹤代碼,逐個分析

1.應用程序 main

int main(void)
{
	char mqname[NAMESIZE], msgrv1[BUFFER], msgrv2[BUFFER];
	const char *msgptr1 = "test message1";
	const char *msgptr2 = "test message2 with differnet length";
	mqd_t mqdes;
	int prio1 = 1, prio2 = 2;
	struct timespec ts;
	struct mq_attr attr;
	int unresolved = 0, failure = 0;
	sprintf(mqname, "/" FUNCTION "_" TEST "_%d", getpid());
	attr.mq_msgsize = BUFFER;
	attr.mq_maxmsg = BUFFER;
	mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr);
	if (mqdes == (mqd_t)-1) {
		perror(ERROR_PREFIX "mq_open");
		unresolved = 1;
	}
	if (mq_send(mqdes, msgptr1, strlen(msgptr1), prio1) != 0) {
		perror(ERROR_PREFIX "mq_send");
		unresolved = 1;
	}
	printf("Test PASSED\n");
	return PTS_PASS;
}

2. mq_open 發起系統調用

mqd_t mq_open(const char *name, int flags, ...)
{
	mode_t mode = 0;
	struct mq_attr *attr = 0;
	if (*name == '/') name++;
	if (flags & O_CREAT) {
		va_list ap;
		va_start(ap, flags);
		mode = va_arg(ap, mode_t);
		attr = va_arg(ap, struct mq_attr *);
		va_end(ap);
	}
	return syscall(SYS_mq_open, name, flags, mode, attr);
}

解讀

SYS_mq_open是真正的系統調用函數,對應一個系統調用號__NR_mq_open,通過宏SYSCALL_HAND_DEF將SysMqOpen注冊到g_syscallHandle中.

static UINTPTR g_syscallHandle[SYS_CALL_NUM] = {0};	//系統調用入口函數注冊
static UINT8 g_syscallNArgs[(SYS_CALL_NUM + 1) / NARG_PER_BYTE] = {0};//保存系統調用對應的參數數量
#define SYSCALL_HAND_DEF(id, fun, rType, nArg)                                             \
    if ((id) < SYS_CALL_NUM) {                                                             \
        g_syscallHandle[(id)] = (UINTPTR)(fun);                                            \
        g_syscallNArgs[(id) / NARG_PER_BYTE] |= ((id) & 1) ? (nArg) << NARG_BITS : (nArg); \
    }                                                                                      \

    #include "syscall_lookup.h"
#undef SYSCALL_HAND_DEF

SYSCALL_HAND_DEF(__NR_mq_open, SysMqOpen, mqd_t, ARG_NUM_4)  

g_syscallNArgs為注冊函數的參數個數,也會一塊記錄下來.

四個參數為 SYS_mq_open的四個參數,后續將保存在R0~R3寄存器中

3. syscall

long syscall(long n, ...)
{
	va_list ap;
	syscall_arg_t a,b,c,d,e,f;
	va_start(ap, n);
	a=va_arg(ap, syscall_arg_t);
	b=va_arg(ap, syscall_arg_t);
	c=va_arg(ap, syscall_arg_t);
	d=va_arg(ap, syscall_arg_t);
	e=va_arg(ap, syscall_arg_t);
	f=va_arg(ap, syscall_arg_t);//最多6個參數
	va_end(ap);
	return __syscall_ret(__syscall(n,a,b,c,d,e,f));
}
//4個參數的系統調用時底層處理
static inline long __syscall4(long n, long a, long b, long c, long d)
{
	register long a7 __asm__("a7") = n; //將系統調用號保存在R7寄存器
	register long a0 __asm__("a0") = a; //R0
	register long a1 __asm__("a1") = b; //R1
	register long a2 __asm__("a2") = c; //R2
	register long a3 __asm__("a3") = d; //R3
	__asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
}

解讀

可變參數實現所有系統調用的參數的管理,可以看出,在鴻蒙內核中系統調用的參數最多不能大于6個

R7寄存器保存了系統調用號,R0~R5保存具體每個參數

可變參數的具體實現后續有其余篇幅詳細介紹,敬請關注.

4. svc 0

//切到SVC模式
#define __asm_syscall(...) do { \
	__asm__ __volatile__ ( "svc 0" \
	: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
	return x0; \
	} while (0)

看不太懂的沒關系,這里我們只需要記住:系統調用號存放在r7寄存器,參數存放在r0,r1,r2寄存器中,返回值最終會存放在寄存器r0中

    b   reset_vector            @開機代碼
    b   _osExceptUndefInstrHdl 	@異常處理之CPU碰到不認識的指令
    b   _osExceptSwiHdl			@異常處理之:軟中斷
    b   _osExceptPrefetchAbortHdl	@異常處理之:取指異常
    b   _osExceptDataAbortHdl		@異常處理之:數據異常
    b   _osExceptAddrAbortHdl		@異常處理之:地址異常
    b   OsIrqHandler				@異常處理之:硬中斷
    b   _osExceptFiqHdl				@異常處理之:快中斷

解讀

svc全稱是 SuperVisor Call,完成工作模式的切換.不管之前是7個模式中的哪個模式,統一都切到SVC管理模式.但你也許會好奇,ARM軟中斷不是用SWI嗎,這里怎么變成了SVC了,請看下面一段話,是從ARM官網翻譯的:

SVC 超級用戶調用。 語法 SVC{cond} #immed 其中: cond 是一個可選的條件代碼(請參閱條件執行)。 immed 是一個表達式,其取值為以下范圍內的一個整數: 在 ARM 指令中為 0 到 224–1(24 位值) 在 16 位 Thumb 指令中為 0-255(8 位值)。 用法 SVC 指令會引發一個異常。 這意味著處理器模式會更改為超級用戶模式,CPSR 會保存到超級用戶模式 SPSR,并且執行會跳轉到 SVC 向量(請參閱《開發指南》中的第 6 章 處理處理器異常)。 處理器會忽略 immed。 但異常處理程序會獲取它,借以確定所請求的服務。 Note 作為 ARM 匯編語言開發成果的一部分,SWI 指令已重命名為 SVC。 在此版本的 RVCT 中,SWI 指令反匯編為 SVC,并提供注釋以指明這是以前的 SWI。 條件標記 此指令不更改標記。 體系結構 此 ARM 指令可用于所有版本的 ARM 體系結構。

而軟中斷對應的處理函數為_osExceptSwiHdl,即PC寄存器將跳到_osExceptSwiHdl執行

5. _osExceptSwiHdl

@ Description: Software interrupt exception handler
_osExceptSwiHdl: @軟中斷異常處理
    @保存任務上下文(TaskContext) 開始... 一定要對照TaskContext來理解
    SUB     SP, SP, #(4 * 16)	@先申請16個棧空間用于處理本次軟中斷
    STMIA   SP, {R0-R12}		@TaskContext.R[GEN_REGS_NUM] STMIA從左到右執行,先放R0 .. R12
    MRS     R3, SPSR			@讀取本模式下的SPSR值
    MOV     R4, LR				@保存回跳寄存器LR

    AND     R1, R3, #CPSR_MASK_MODE                          @ Interrupted mode 獲取中斷模式
    CMP     R1, #CPSR_USER_MODE                              @ User mode	是否為用戶模式
    BNE     OsKernelSVCHandler                               @ Branch if not user mode 非用戶模式下跳轉
	@ 當為用戶模式時,獲取SP和LR寄出去值
    @ we enter from user mode, we need get the values of  USER mode r13(sp) and r14(lr).
    @ stmia with ^ will return the user mode registers (provided that r15 is not in the register list).
    MOV     R0, SP											 @獲取SP值,R0將作為OsArmA32SyscallHandle的參數
    STMFD   SP!, {R3}                                        @ Save the CPSR 入棧保存CPSR值 => TaskContext.regPSR
    ADD     R3, SP, #(4 * 17)                                @ Offset to pc/cpsr storage 跳到PC/CPSR存儲位置
    STMFD   R3!, {R4}                                        @ Save the CPSR and r15(pc) 保存LR寄存器 => TaskContext.PC
    STMFD   R3, {R13, R14}^                                  @ Save user mode r13(sp) and r14(lr) 從右向左 保存 => TaskContext.LR和SP
    SUB     SP, SP, #4										 @ => TaskContext.resved
    PUSH_FPU_REGS R1	@保存中斷模式(用戶模式模式)											
	@保存任務上下文(TaskContext) 結束
    MOV     FP, #0                                           @ Init frame pointer
    CPSIE   I	@開中斷,表明在系統調用期間可響應中斷
    BLX     OsArmA32SyscallHandle	/*交給C語言處理系統調用,參數為R0,指向TaskContext的開始位置*/
    CPSID   I	@執行后續指令前必須先關中斷
	@恢復任務上下文(TaskContext) 開始
    POP_FPU_REGS R1											 @彈出FP值給R1
    ADD     SP, SP,#4										 @ 定位到保存舊SPSR值的位置
    LDMFD   SP!, {R3}                                        @ Fetch the return SPSR 彈出舊SPSR值
    MSR     SPSR_cxsf, R3                                    @ Set the return mode SPSR 恢復該模式下的SPSR值

    @ we are leaving to user mode, we need to restore the values of USER mode r13(sp) and r14(lr).
    @ ldmia with ^ will return the user mode registers (provided that r15 is not in the register list)

    LDMFD   SP!, {R0-R12}									 @恢復R0-R12寄存器
    LDMFD   SP, {R13, R14}^                                  @ Restore user mode R13/R14 恢復用戶模式的R13/R14寄存器
    ADD     SP, SP, #(2 * 4)								 @定位到保存舊PC值的位置
    LDMFD   SP!, {PC}^                                       @ Return to user 切回用戶模式運行
	@恢復任務上下文(TaskContext) 結束

OsKernelSVCHandler:@主要目的是保存ExcContext中除(R0~R12)的其他寄存器
    ADD     R0, SP, #(4 * 16)	@跳轉到保存PC,LR,SP的位置,此時R0位置剛好是SP的位置
    MOV     R5, R0				@由R5記錄SP位置,因為R0要暫時充當SP寄存器來使用
    STMFD   R0!, {R4}                                        @ Store PC => ExcContext.PC
    STMFD   R0!, {R4}										 @ 相當于保存了=>  ExcContext.LR
    STMFD   R0!, {R5}										 @ 相當于保存了=>  ExcContext.SP

    STMFD   SP!, {R3}                                        @ Push task`s CPSR (i.e. exception SPSR). =>ExcContext.regPSR
    SUB     SP, SP, #(4 * 2)                                 @ user sp and lr => =>ExcContext.USP,ULR

    MOV     R0, #OS_EXCEPT_SWI                               @ Set exception ID to OS_EXCEPT_SWI.
															 @ 設置異常ID為軟中斷
    B       _osExceptionSwi                                  @ Branch to global exception handler.
															 @ 跳到全局異常處理
    解讀

運行到此處,已經切到SVC的棧運行,所以先保存上一個模式的現場

獲取中斷模式,軟中斷的來源可不一定是用戶模式,完全有可能是SVC本身,比如系統調用中又發生系統調用.就變成了從SVC模式切到SVC的模式

MOV R0, SP;sp將作為參數傳遞給OsArmA32SyscallHandle

調用OsArmA32SyscallHandle這是所有系統調用的統一入口

注意看OsArmA32SyscallHandle的參數UINT32 *regs

6. OsArmA32SyscallHandle

/* The SYSCALL ID is in R7 on entry.  Parameters follow in R0..R6 */
/******************************************************************
由匯編調用,見于 los_hw_exc.s    / BLX    OsArmA32SyscallHandle
SYSCALL是產生系統調用時觸發的信號,R7寄存器存放具體的系統調用ID,也叫系統調用號
regs:參數就是所有寄存器
注意:本函數在用戶態和內核態下都可能被調用到
//MOV     R0, SP @獲取SP值,R0將作為OsArmA32SyscallHandle的參數
******************************************************************/
LITE_OS_SEC_TEXT UINT32 *OsArmA32SyscallHandle(UINT32 *regs)
{
    UINT32 ret;
    UINT8 nArgs;
    UINTPTR handle;
    UINT32 cmd = regs[REG_R7];//C7寄存器記錄了觸發了具體哪個系統調用
	
    if (cmd >= SYS_CALL_NUM) {//系統調用的總數
        PRINT_ERR("Syscall ID: error %d !!!\n", cmd);
        return regs;
    }

    if (cmd == __NR_sigreturn) {//收到 __NR_sigreturn 信號
        OsRestorSignalContext(regs);//恢復信號上下文
        return regs;
    }

    handle = g_syscallHandle[cmd];//拿到系統調用的注冊函數,類似 SysRead 
    nArgs = g_syscallNArgs[cmd / NARG_PER_BYTE]; /* 4bit per nargs */
    nArgs = (cmd & 1) ? (nArgs >> NARG_BITS) : (nArgs & NARG_MASK);//獲取參數個數
    if ((handle == 0) || (nArgs > ARG_NUM_7)) {//系統調用必須有參數且參數不能大于8個
        PRINT_ERR("Unsupport syscall ID: %d nArgs: %d\n", cmd, nArgs);
        regs[REG_R0] = -ENOSYS;
        return regs;
    }
	//regs[0-6] 記錄系統調用的參數,這也是由R7寄存器保存系統調用號的原因
    switch (nArgs) {//參數的個數 
        case ARG_NUM_0:
        case ARG_NUM_1:
            ret = (*(SyscallFun1)handle)(regs[REG_R0]);//執行系統調用,類似 SysUnlink(pathname);
            break;
        case ARG_NUM_2://如何是兩個參數的系統調用,這里傳三個參數也沒有問題,因被調用函數不會去取用R2值
        case ARG_NUM_3:
            ret = (*(SyscallFun3)handle)(regs[REG_R0], regs[REG_R1], regs[REG_R2]);//類似 SysExecve(fileName, argv, envp);
            break;
        case ARG_NUM_4:
        case ARG_NUM_5:
            ret = (*(SyscallFun5)handle)(regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
                                         regs[REG_R4]);
            break;
        default:	//7個參數的情況
            ret = (*(SyscallFun7)handle)(regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
                                         regs[REG_R4], regs[REG_R5], regs[REG_R6]);
    }

    regs[REG_R0] = ret;//R0保存系統調用返回值
    OsSaveSignalContext(regs);//保存信號上下文現場

    /* Return the last value of curent_regs.  This supports context switches on return from the exception.
     * That capability is only used with theSYS_context_switch system call.
     */
    return regs;//返回寄存器的值
}

解讀

參數是regs對應的就是R0~Rn

R7保存的是系統調用號,R0~R3保存的是SysMqOpen的四個參數

g_syscallHandle[cmd]就能查詢到SYSCALL_HAND_DEF(__NR_mq_open, SysMqOpen, mqd_t, ARG_NUM_4)注冊時對應的SysMqOpen函數

*(SyscallFun5)handle此時就是SysMqOpen

注意看 SysMqOpen 的參數是最開始的main函數中的mqdes = mq_open(mqname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, &attr);由此完成了真正系統調用的過程

7. SysMqOpen

mqd_t SysMqOpen(const char *mqName, int openFlag, mode_t mode, struct mq_attr *attr)
{
    mqd_t ret;
    int retValue;
    char kMqName[PATH_MAX + 1] = { 0 };

    retValue = LOS_StrncpyFromUser(kMqName, mqName, PATH_MAX);
    if (retValue < 0) {
        return retValue;
    }
    ret = mq_open(kMqName, openFlag, mode, attr);//一個消息隊列可以有多個進程向它讀寫消息
    if (ret == -1) {
        return (mqd_t)-get_errno();
    }
    return ret;
}

解讀

此處的mq_open和main函數的mq_open其實是兩個函數體實現.一個是給應用層的調用,一個是內核層使用,只是名字一樣而已.

SysMqOpen是返回到OsArmA32SyscallHandleregs[REG_R0] = ret;

OsArmA32SyscallHandle再返回到_osExceptSwiHdl

_osExceptSwiHdl后面的代碼是用于恢復用戶模式現場和SPSR,PC等寄存器.

以上為鴻蒙系統調用的整個過程.

編輯:hfy

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5608

    瀏覽量

    129968
  • 鴻蒙系統
    +關注

    關注

    183

    文章

    2642

    瀏覽量

    69832
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Linux內核編碼風格權威總結:從縮進到底層設計,讓你的代碼更“內核味”

    作為全球最龐大的開源項目之一,Linux 內核代碼量早已突破千萬行。要讓來自世界各地的開發者高效協作,一套統一、嚴謹的編碼風格必不可少 —— 這不僅是 “代碼顏值” 的要求,更是可讀性、可維護性的核心保障。
    的頭像 發表于 02-09 16:29 ?122次閱讀
    Linux<b class='flag-5'>內核</b>編碼風格權威總結:從縮進到底層設計,讓你的<b class='flag-5'>代碼</b>更“<b class='flag-5'>內核</b>味”

    代碼照亮未來:蘭州大學開源鴻蒙技術俱樂部的六種青春答卷

    ;沒有單打獨斗的英雄,只有并肩攻堅的戰友。從內核調試到應用創新,從社區貢獻到生態布道,這群心懷“技術報國”理想的青年,正在用一行行代碼構建開源鴻蒙的明天。 這六位同學,正是技術俱樂部百余名成員的代表,他們的故事
    的頭像 發表于 01-19 16:58 ?523次閱讀
    <b class='flag-5'>代碼</b>照亮未來:蘭州大學開源<b class='flag-5'>鴻蒙</b>技術俱樂部的六種青春答卷

    德州儀器BCD到七段譯碼器/驅動器深度剖析

    德州儀器BCD到七段譯碼器/驅動器深度剖析 在數字電路設計中,BCD到七段譯碼器/驅動器是實現數字顯示的關鍵組件。德州儀器(TI)的SN5446A、’47A、’48、SN54LS47、’LS48
    的頭像 發表于 01-19 11:30 ?270次閱讀

    德州儀器BCD到七段譯碼器/驅動器:設計與應用指南

    德州儀器BCD到七段譯碼器/驅動器:設計與應用指南 在電子電路設計中,將二進制編碼十進制(BCD)信號轉換為七段數碼管顯示信號是一項常見且關鍵的任務。德州儀器(TI)的SN54246、SN54247
    的頭像 發表于 01-19 11:25 ?248次閱讀

    內核到生態:一次看懂HarmonyOS 6如何重寫操作系統的“基礎代碼

    “基礎代碼”的重寫,它以五大核心架構為基石,構建了一個面向萬物互聯時代、兼具極致性能、主動安全與原生智能的新一代系統底座。 鴻蒙內核與方舟引擎:性能之基,流暢之源 “方舟引擎讓軟、硬、生態高效協同,實現1+1+1>3的效果?!彼?/div>
    的頭像 發表于 12-31 09:09 ?260次閱讀
    從<b class='flag-5'>內核</b>到生態:一次看懂HarmonyOS 6如何重寫操作系統的“基礎<b class='flag-5'>代碼</b>”

    鴻蒙星光盛典見證生態碩果!深開鴻斬獲開源鴻蒙雙項榮譽

    近日,鴻蒙星光盛典生態論壇在深圳隆重舉辦。作為開源鴻蒙生態的核心共建者,深開鴻受邀出席這一盛會,與眾多生態伙伴共話技術創新,共繪生態未來。在開源鴻蒙行業分論壇上,深開鴻以其在社區代碼
    的頭像 發表于 12-02 15:17 ?611次閱讀
    <b class='flag-5'>鴻蒙</b>星光盛典見證生態碩果!深開鴻斬獲開源<b class='flag-5'>鴻蒙</b>雙項榮譽

    Linux內核模塊的加載機制

    \"GPL\") bool sig_ok;// 簽名驗證結果 };然后進行內存分配 1、使用vmalloc()在內核空間分配內存,映射模塊的代碼和數據。 2、標記可執行頁(需
    發表于 11-25 06:59

    開源鴻蒙技術大會2025丨OS內核與視窗分論壇:筑基開源鴻蒙核心內核,共拓視窗技術邊界

    開源鴻蒙技術大會2025 OS內核與視窗分論壇在湖南長沙國際會議中心圓滿舉行。來自西北工業大學、浙江大學、廈門大學、華為等高校和企業的學者專家齊聚一堂,圍繞鴻蒙內核通信機制、智能渲染、
    的頭像 發表于 11-20 17:29 ?864次閱讀
    開源<b class='flag-5'>鴻蒙</b>技術大會2025丨OS<b class='flag-5'>內核</b>與視窗分論壇:筑基開源<b class='flag-5'>鴻蒙</b>核心<b class='flag-5'>內核</b>,共拓視窗技術邊界

    在qemu上體驗芯來RISC-V處理器運行鴻蒙LiteOS-M內核

    在qemu上體驗芯來RISC-V處理器運行鴻蒙LiteOS-M內核 1.本文概述 2.下載qemu 3.下載鴻蒙LiteOS-M 4.運行與測試 5.gdb調試 1.本文概述 由于前幾天
    發表于 10-31 09:04

    目標追蹤的簡易實現:模板匹配

    往往是先在一個靜態的圖象中尋找到某一片像素區域(比如從背景畫面中框選出人臉或文字),然后再對這片像素區域作分析(比如提取人臉關鍵點信息等等);而目標追蹤則是在一視頻流中進行,它根據指定的追蹤
    發表于 10-28 07:21

    如何防止七段顯示器上的重影?

    發表于 09-05 08:17

    知乎開源“智能預渲染框架” 幾行代碼實現鴻蒙應用頁面“秒開”

    ,交互延遲等核心痛點,通過智能預測用戶瀏覽目標進行提前渲染,只需幾行代碼即可顯著提升復雜頁面的加載性能,實現“頁面秒開”的高效體驗,為鴻蒙開發者帶來開發效率和用戶體驗的雙重飛躍。 隨著鴻蒙生態快速發展,應用開發者難免會遇到一些性
    的頭像 發表于 08-29 14:32 ?627次閱讀
    知乎開源“智能預渲染框架” 幾行<b class='flag-5'>代碼</b>實現<b class='flag-5'>鴻蒙</b>應用頁面“秒開”

    鴻蒙5開發寶藏案例分享---Grid性能優化案例

    注意到。今天我就帶大家拆解這個案例,加上詳細講解和代碼分析,幫你輕松提升應用流暢度! ?問題場景:為什么Grid會卡? 當Grid布局需要實現 不規則網格 (比如合并單元格)時,我們常用<
    發表于 06-12 17:47

    鴻蒙5開發寶藏案例分享---分析幀率問題

    鴻蒙性能優化寶藏:幀率問題實戰案例解析 嘿,各位鴻蒙開發者! 今天分享一個開發中的大發現——鴻蒙官方文檔里藏著一堆超實用的性能優化案例!這些案例不僅解決了常見的丟幀卡頓問題,還附帶了詳細的分析
    發表于 06-12 17:07

    鴻蒙5開發寶藏案例分享---點擊完成時延分析

    ... profiler.stopTrace(\'page_switch\'); 幀率分析:揪出超時渲染幀(紅色警告幀) 調用棧追蹤:ArkTS/Native雙視角分析 支持冷啟動/卡頓/內存等場景深度優化
    發表于 06-12 17:03