1. HarmonyOS應(yīng)用打包后的文件擴(kuò)展名是?
打包后的文件擴(kuò)展名為.hap(HarmonyOS Ability Package)踊谋,這是HarmonyOS應(yīng)用的標(biāo)準(zhǔn)包格式
2. 頁面和自定義組件生命周期有哪些?
有@Entry裝飾器的@component組件的生命周期
onPageShow:頁面每次顯示時觸發(fā)一次恨诱,包括路由過程、應(yīng)用進(jìn)入前臺等場景。
onPageHide:頁面每次隱藏時觸發(fā)一次,包括路由過程、應(yīng)用進(jìn)入后臺等場景署鸡。
onBackPress:當(dāng)用戶點(diǎn)擊返回按鈕時觸發(fā)。
有@Entry裝飾器和無@Entry裝飾器@Component組件都有的生命周期
aboutToAppear:組件即將出現(xiàn)時回調(diào)該接口限嫌,具體時機(jī)為在創(chuàng)建自定義組件的新實例后靴庆,在執(zhí)行其 build()函數(shù)之前執(zhí)行。
onDidBuild:API12新增怒医,組件 build()函數(shù)執(zhí)行完成之后回調(diào)該接口炉抒,不建議在 onDidBuild函數(shù)中更改狀態(tài)變量、使用 animateTo等功能稚叹,這會導(dǎo)致不穩(wěn)定的UI表現(xiàn)焰薄。
aboutToDisappear:aboutToDisappear函數(shù)在自定義組件析構(gòu)銷毀之前執(zhí)行。不允許在aboutToDisappear函數(shù)中改變狀態(tài)變量扒袖,特別是@Link變量的修改會導(dǎo)致應(yīng)用程序行為不穩(wěn)定塞茅。
3. 如何進(jìn)行數(shù)據(jù)持久化?
用戶首選項(Preferences):這是一種輕量級的配置數(shù)據(jù)持久化方式,適用于保存應(yīng)用配置信息季率、用戶偏好設(shè)置等野瘦。它通過文本形式保存數(shù)據(jù),并且數(shù)據(jù)會全量加載到內(nèi)存中飒泻,因此訪問速度快鞭光,但不適合存儲大量數(shù)據(jù)。
鍵值型數(shù)據(jù)庫(KV-Store):適用于存儲結(jié)構(gòu)簡單的數(shù)據(jù),如商品名稱和價格灵再、員工工號和出勤狀態(tài)等。鍵值型數(shù)據(jù)庫以“鍵值對”的形式組織數(shù)據(jù),適合數(shù)據(jù)關(guān)系不復(fù)雜的場景发笔。
關(guān)系型數(shù)據(jù)庫(RelationalStore):基于SQLite,適用于存儲包含復(fù)雜關(guān)系的數(shù)據(jù)榄攀,如學(xué)生信息掘托、雇員信息等。關(guān)系型數(shù)據(jù)庫提供了一系列SQL操作畦戒,如增刪改查等方库。
4. 如何進(jìn)行全局狀態(tài)管理?
@Provide+@Consume裝飾器 適用場景:適用于整個組件樹而言“全局”的狀態(tài)共享,且該狀態(tài)改動不頻繁的場景障斋。 工作原理:通過在最頂層組件中使用 @Provide裝飾器提供狀態(tài)纵潦,其他需要共享狀態(tài)的組件通過 @Consume裝飾器獲取該狀態(tài) 徐鹤。 優(yōu)點(diǎn):減少了狀態(tài)傳遞的層級,提升了代碼的可維護(hù)性和可拓展性邀层。 注意事項:確保狀態(tài)的生命周期與組件樹的生命周期一致返敬,避免不必要的UI刷新。
AppStorage 適用場景:適用于整個應(yīng)用而言“全局”的變量或應(yīng)用的主線程內(nèi)多個 UIAbility實例間的狀態(tài)共享寥院。 工作原理:AppStorage與應(yīng)用的進(jìn)程綁定劲赠,由UI框架在應(yīng)用程序啟動時創(chuàng)建,當(dāng)應(yīng)用進(jìn)程終止秸谢,AppStorage被回收凛澎。 優(yōu)點(diǎn):適用于需要在整個應(yīng)用中共享狀態(tài)的場景。 注意事項:確保狀態(tài)的生命周期與應(yīng)用進(jìn)程一致估蹄,避免在應(yīng)用退出后仍有狀態(tài)存在塑煎。
LocalStorage 適用場景:適用于單個Ability而言“全局”的變量,主要用于不同頁面間的狀態(tài)共享臭蚁。 工作原理:LocalStorage的生命周期由應(yīng)用程序決定轧叽,當(dāng)應(yīng)用釋放最后一個指向 LocalStorage的引用時,LocalStorage被垃圾回收刊棕。 優(yōu)點(diǎn):適用于需要在單個UIAbility中不同頁面間共享狀態(tài)的場景炭晒。 注意事項:確保狀態(tài)的生命周期與應(yīng)用程序的生命周期一致,避免在應(yīng)用退出后仍有狀態(tài)存在甥角。
5. LocalStorage在應(yīng)用重啟后數(shù)據(jù)會消失嗎?
會,因為LocalStorage 是一種用于頁面或組件級別的數(shù)據(jù)存儲方式网严,它允許開發(fā)者在頁面或組件的生命周期內(nèi)存儲和檢索數(shù)據(jù)。LocalStorage 的數(shù)據(jù)存儲在內(nèi)存中嗤无,因此它的讀寫速度相對較快震束。但是,當(dāng)應(yīng)用重啟后当犯,LocalStorage 中的數(shù)據(jù)會丟失垢村。
6. 父子組件如何通信?
@Prop裝飾器、@Link裝飾器嚎卫、@Provide和@Consume裝飾器嘉栓、@Event裝飾器、@Parame裝飾器拓诸、@Provider裝飾器和@Consumer裝飾器 當(dāng)前(API 12)狀態(tài)管理有兩個版本 @Component和 @ComponentV2
父子單向數(shù)據(jù)傳遞 @State+@Prop @Prop裝飾的變量可以和父組件建立單向的同步關(guān)系侵佃。@Prop裝飾的變量是可變的,但是變化不會同步回其父組件奠支。
父子雙向數(shù)據(jù)傳遞 @State+@Link 馋辈、@objectLink+@Link 子組件中被 @Link裝飾的變量與其父組件中對應(yīng)的數(shù)據(jù)源建立雙向數(shù)據(jù)綁定。
跨組件通信 @Provide裝飾器和 @Consume裝飾器 @Provide和 @Consume倍谜,應(yīng)用于與后代組件的雙向數(shù)據(jù)同步迈螟,應(yīng)用于狀態(tài)數(shù)據(jù)在多個層級之間傳遞的場景叉抡。不同于 @Prop和 @Link,@Provide和 @Consume擺脫參數(shù)傳遞機(jī)制的束縛答毫,實現(xiàn)跨層級傳遞褥民。
@Observed裝飾器和 @ObjectLink裝飾器 對于多層嵌套的情況,比如二維數(shù)組烙常,或者數(shù)組項class轴捎,或者class的屬性是class,他們的第二層的屬性變化是無法觀察到的蚕脏。這就要用到 @Observed/@ObjectLink裝飾器 注意:@ObjectLink裝飾器不能在 @Entry裝飾的自定義組件中使用且 @ObjectLink 裝飾的變量不能被賦值,只能對其屬性進(jìn)行賦值操作
7. 兄弟組件如何通信?
通過公共父組件傳遞 如果兩個組件是同一個父組件的子組件侦副,可以通過父組件來傳遞數(shù)據(jù)或事件。父組件可以作為中介驼鞭,將一個子組件的數(shù)據(jù)或事件傳遞給另一個子組件秦驯。
使用全局狀態(tài)管理 使用全局狀態(tài)管理(如 AppStorage、LocalStorage)來存儲共享數(shù)據(jù)挣棕。兄弟組件可以獨(dú)立地讀取和更新這個全局狀態(tài)译隘,從而實現(xiàn)通信。
8. 如何實現(xiàn)頁面間的通信?
使用 @Provide和 @Consume裝飾器(見6.3)
使用路由跳轉(zhuǎn)傳參
import{router}from'@kit.ArkUI';
router.pushUrl({
url:'pages/Detail',// 目標(biāo)url
params:paramsInfo// 添加params屬性洛心,傳遞自定義參數(shù)
})
// 返回指定頁面并攜帶參數(shù)
router.back({
url:'pages/Home',
params: {
info:'來自Home頁'
? }
});
使用導(dǎo)航跳轉(zhuǎn)傳參
this.pageStack.pushPath({name:"PageOne",param:"PageOne Param"})
this.pageStack.pushPathByName("PageOne","PageOne Param")
9. Navigation組件跳轉(zhuǎn)和router跳轉(zhuǎn)有什么區(qū)別?
Navigation:是路由容器組件,適用于模塊內(nèi)和跨模塊的路由切換词身,一次開發(fā)厅目,多端部署場景。Router位于頁面棧管理節(jié)點(diǎn) stage 下面法严,不提供導(dǎo)航容器的概念损敷。
Navigation和 Router都支持跳轉(zhuǎn)傳參,但 Router對象中暫不支持方法變量深啤。
Navigation:支持清理指定路由拗馒,頁面棧沒有上限,可以無限跳轉(zhuǎn)溯街。Router不支持清理指定路由且頁面棧最大為32诱桂,頁面棧到達(dá)32之后必須清除之后才能繼續(xù)跳轉(zhuǎn)。
Navigation:支持自定義轉(zhuǎn)場動畫和共享元素轉(zhuǎn)場動畫苫幢。 Router:僅支持簡單自定義轉(zhuǎn)場動畫访诱。
Navigation:支持通過 setInterception 方法設(shè)置路由攔截。Router:不支持路由攔截韩肝。
Navigation:支持沉浸式頁面和模態(tài)嵌套路由。Router:不支持九榔,需要通過窗口配置實現(xiàn)沉浸式頁面哀峻。
總而言之涡相,Navigation 組件在功能上更具豐富性和靈活性,特別是在處理復(fù)雜的導(dǎo)航結(jié)構(gòu)剩蟀、動效和路由管理方面催蝗。 而 Router 則提供了更基礎(chǔ)的路由跳轉(zhuǎn)功能,適合簡單的路由需求育特。開發(fā)者可以根據(jù)應(yīng)用的具體需求和設(shè)計選擇最合適的路由方案丙号。
具體的區(qū)別如下表:
業(yè)務(wù)場景NavigationRouter
一多能力支持,Auto模式自適應(yīng)單欄跟雙欄顯示不支持
跳轉(zhuǎn)指定頁面pushPath & pushDestinationpushUrl & pushNameRoute
跳轉(zhuǎn)HSP中頁面支持支持
跳轉(zhuǎn)HAR中頁面支持支持
跳轉(zhuǎn)傳參支持支持
獲取指定頁面參數(shù)支持不支持
傳參類型傳參為對象形式傳參為對象形式缰冤,對象中暫不支持方法變量
跳轉(zhuǎn)結(jié)果回調(diào)支持支持
跳轉(zhuǎn)單例頁面支持支持
頁面返回支持支持
頁面返回傳參支持支持
返回指定路由支持支持
頁面返回彈窗支持犬缨,通過路由攔截實現(xiàn)showAlertBeforeBackPage
路由替換replacePath & replacePathByNamereplaceUrl & replaceNameRoute
路由棧清理clearclear
清理指定路由removeByIndexes & removeByName不支持
轉(zhuǎn)場動畫支持支持
自定義轉(zhuǎn)場動畫支持支持,動畫類型受限
屏蔽轉(zhuǎn)場動畫支持全局和單次支持 設(shè)置pageTransition方法duration為0
geometryTransition共享元素動畫支持(NavDestination之間共享)不支持
頁面生命周期監(jiān)聽UIObserver.on('navDestinationUpdate')UIObserver.on('routerPageUpdate')
獲取頁面棧對象支持不支持
路由攔截支持通過setInterception做路由攔截不支持
路由棧信息查詢支持getState() & getLength()
路由棧move操作moveToTop & moveIndexToTop不支持
沉浸式頁面支持不支持棉浸,需通過window配置
設(shè)置頁面標(biāo)題欄(titlebar)和工具欄(toolbar)支持不支持
模態(tài)嵌套路由支持不支持
10. HarmonyOS與Android和iOS有什么區(qū)別怀薛?
HarmonyOS 是華為開發(fā)的一個開源、分布式的操作系統(tǒng)迷郑。它設(shè)計用于多種設(shè)備枝恋,包括智能手機(jī)、平板電腦嗡害、智能電視和物聯(lián)網(wǎng)設(shè)備焚碌。與Android和iOS的主要區(qū)別在于:
分布式架構(gòu):HarmonyOS支持跨設(shè)備無縫協(xié)作,允許設(shè)備之間共享硬件資源霸妹。
性能:HarmonyOS優(yōu)化了任務(wù)調(diào)度和內(nèi)存管理十电,提高了性能和響應(yīng)速度。
安全性:HarmonyOS采用了多層次的安全策略抑堡,包括數(shù)據(jù)加密和安全啟動摆出。
生態(tài)系統(tǒng):HarmonyOS正在構(gòu)建自己的應(yīng)用生態(tài)系統(tǒng),鼓勵開發(fā)者使用Ark Ts和ArkUI框架首妖。
11. 什么是Ability偎漫?
Ability是應(yīng)用/服務(wù)所具備的能力的抽象,一個Module可以包含一個或多個 Ability ,在鴻蒙系統(tǒng)中有缆,Ability提供了對 Ability生命周期象踊、上下文環(huán)境等調(diào)用管理的能力,包括 Ability創(chuàng)建棚壁、銷毀杯矩、轉(zhuǎn)儲客戶端信息等
鴻蒙系統(tǒng)中的 Ability主要分為兩種類型:UIAbility和 ExtensionAbility。
UIAbility :
定義 :包含UI界面袖外,提供展示UI的能力史隆,主要用于和用戶交互 。
創(chuàng)建 :在模塊中添加UIAbility時曼验,選中對應(yīng)的模塊泌射,單擊鼠標(biāo)右鍵粘姜,選擇New > Ability,設(shè)置Ability名稱熔酷,選擇是否在設(shè)備主屏幕上顯示該功能的啟動圖標(biāo)孤紧,單擊Finish完成Ability創(chuàng)建 。
ExtensionAbility :
定義 :提供特定場景的擴(kuò)展能力拒秘,滿足更多的使用場景 号显。
創(chuàng)建 :在模塊中添加ExtensionAbility時,選中對應(yīng)的模塊躺酒,單擊鼠標(biāo)右鍵押蚤,選擇不同的場景類型(如Accessibility、EmbeddedUIExtensionAbility等) 阴颖。當(dāng)前僅Application工程支持創(chuàng)建ExtensionAbility活喊。設(shè)置Ability名稱,單擊Finish完成ExtensionAbility創(chuàng)建量愧。
此外钾菊,Ability是Ability模塊的基類,提供系統(tǒng)配置更新回調(diào)和系統(tǒng)內(nèi)存調(diào)整回調(diào) 偎肃。Ability的繼承關(guān)系包括UIAbility和ExtensionAbility等具體類.
總之煞烫,Ability是鴻蒙系統(tǒng)中用于管理應(yīng)用能力的核心組件,通過不同類型的Ability可以實現(xiàn)不同的功能需求累颂。
12. ArkUI框架有哪些特點(diǎn)滞详?
ArkUI框架是鴻蒙(HarmonyOS)中的一個重要組件框架,具有以下幾個特點(diǎn):
組件樹結(jié)構(gòu) : ArkUI框架通過布局組件和基礎(chǔ)組件構(gòu)建界面描述樹(組件樹)紊馏,其中基礎(chǔ)組件為葉子節(jié)點(diǎn)料饥,布局組件為中間節(jié)點(diǎn) 。當(dāng)用戶進(jìn)行交互時朱监,會觸發(fā)界面修改岸啡,通過重新渲染組件樹來實現(xiàn)應(yīng)用界面更新 。
數(shù)據(jù)與UI更新過程 : ArkUI框架的數(shù)據(jù)處理過程和UI更新過程是分開進(jìn)行的赫编。數(shù)據(jù)處理過程中巡蘸,主要是對狀態(tài)數(shù)據(jù)進(jìn)行更新,并通過標(biāo)臟過程確定布局最小影響范圍擂送,減少不必要的重新布局 悦荒。UI更新過程包括組件標(biāo)臟、布局嘹吨、測量和渲染等階段 搬味。
布局組件 : ArkUI框架提供了多種布局組件,如Row、Column身腻、Stack产还、Flex匹厘、List嘀趟、Grid、RelativeContainer等愈诚。開發(fā)者可以根據(jù)場景選擇合適的布局組件她按,以優(yōu)化性能 。例如炕柔,線性布局(Row酌泰、Column)適用于橫向或縱向排列組件,而彈性布局(Flex)適用于需要彈性排列的場景匕累。
性能優(yōu)化 : ArkUI框架在性能優(yōu)化方面做了很多工作陵刹。例如,通過減少不必要的組件嵌套和節(jié)點(diǎn)數(shù)量欢嘿,降低布局測算的復(fù)雜度衰琐,從而提升性能。開發(fā)者可以使用DevEco Studio提供的工具(如Profiler和ArkUI Inspector)來查看性能瓶頸和組件樹結(jié)構(gòu)炼蹦,進(jìn)一步優(yōu)化應(yīng)用性能羡宙。
狀態(tài)管理 : ArkUI框架支持狀態(tài)管理最佳實踐,通過有效的狀態(tài)管理減少無效的UI更新操作掐隐,提升性能狗热。例如,在狀態(tài)變量變化導(dǎo)致UI更新時虑省,只更新部分組件匿刮,而不是重新渲染整個界面。
13. 跨設(shè)備通信的方式有哪些探颈?
HarmonyOS支持多種跨設(shè)備通信方式熟丸,包括:
分布式軟總線:一種高性能的通信機(jī)制,允許設(shè)備之間建立直接連接膝擂,進(jìn)行數(shù)據(jù)傳輸虑啤。
藍(lán)牙:使用標(biāo)準(zhǔn)的藍(lán)牙技術(shù)進(jìn)行設(shè)備間的通信。
WLAN:通過WLAN網(wǎng)絡(luò)實現(xiàn)設(shè)備間的通信架馋。
遠(yuǎn)程服務(wù)調(diào)用:通過分布式任務(wù)調(diào)度實現(xiàn)跨設(shè)備的服務(wù)調(diào)用狞山。
14. 如何實現(xiàn)應(yīng)用的后臺運(yùn)行?
后臺服務(wù):使用后臺服務(wù)(如BackgroundService)來執(zhí)行不需要用戶直接交互的任務(wù)叉寂。
定時任務(wù):通過系統(tǒng)提供的定時任務(wù)機(jī)制(如AlarmService)來周期性執(zhí)行后臺任務(wù)萍启。
事件監(jiān)聽:注冊系統(tǒng)事件,如網(wǎng)絡(luò)變化、電量變化等勘纯,以在特定事件發(fā)生時喚醒應(yīng)用進(jìn)行處理局服。
15. Ability是如何與用戶交互的?
界面顯示:Ability可以包含一個或多個AbilitySlice驳遵,用于顯示UI界面并與用戶進(jìn)行交互淫奔。
事件處理:Ability可以處理用戶的輸入事件,如觸摸堤结、按鍵等唆迁。
數(shù)據(jù)綁定:Ability可以使用數(shù)據(jù)綁定機(jī)制,將UI組件與數(shù)據(jù)模型綁定竞穷,實現(xiàn)數(shù)據(jù)的自動更新和交互唐责。
通知:Ability可以通過系統(tǒng)通知機(jī)制向用戶發(fā)送通知,即使應(yīng)用不在前臺運(yùn)行瘾带。
16. 如何實現(xiàn)應(yīng)用的多語言支持鼠哥?
資源文件:為每種語言創(chuàng)建資源文件(如string.json),并在里面定義所有可本地化的字符串看政。
資源引用:在代碼中使用資源ID引用字符串朴恳,而不是硬編碼文本。
系統(tǒng)設(shè)置:應(yīng)用會自動根據(jù)系統(tǒng)設(shè)置的語言環(huán)境加載相應(yīng)的資源文件帽衙。
動態(tài)切換:支持在應(yīng)用運(yùn)行時切換語言菜皂,并動態(tài)更新UI。
17. 分布式數(shù)據(jù)庫是如何實現(xiàn)數(shù)據(jù)同步的厉萝?
分布式事務(wù):確被衅跨設(shè)備的數(shù)據(jù)庫操作具有原子性、一致性谴垫、隔離性和持久性章母。
數(shù)據(jù)版本控制:為數(shù)據(jù)添加版本號,確保同步時數(shù)據(jù)的一致性翩剪。
沖突解決策略:定義沖突解決策略乳怎,處理并發(fā)操作導(dǎo)致的數(shù)據(jù)沖突。
網(wǎng)絡(luò)狀態(tài)感知:根據(jù)網(wǎng)絡(luò)狀態(tài)智能同步數(shù)據(jù)前弯,優(yōu)化同步效率和流量使用蚪缀。
18. 如何優(yōu)化應(yīng)用的性能?
內(nèi)存管理:合理分配和釋放內(nèi)存恕出,避免內(nèi)存泄漏询枚。
后臺優(yōu)化:合理使用后臺服務(wù)和定時任務(wù),避免不必要的后臺運(yùn)行浙巫。
UI渲染優(yōu)化:使用輕量級的UI組件金蜀,減少布局復(fù)雜度刷后,優(yōu)化渲染性能。
資源優(yōu)化:壓縮圖片和媒體資源渊抄,減少應(yīng)用的體積和加載時間尝胆。
19. HarmonyOS中的權(quán)限管理模型是怎樣的?
權(quán)限聲明:應(yīng)用在config.json中聲明所需的權(quán)限护桦。
權(quán)限申請:在應(yīng)用運(yùn)行時含衔,根據(jù)需要動態(tài)申請權(quán)限。
權(quán)限檢查:在執(zhí)行敏感操作前嘶炭,檢查是否已獲得相應(yīng)權(quán)限抱慌。
權(quán)限分組:系統(tǒng)將權(quán)限分為不同的組,便于管理和申請眨猎。
20. LazyForEach是什么?
LazyForEach 是一個用于高效渲染列表的組件或功能强经,它允許開發(fā)者在用戶滾動列表時才加載和渲染列表項睡陪,而不是一次性渲染整個列表。這種按需渲染的方式可以顯著提高應(yīng)用的性能匿情,特別是在處理大量數(shù)據(jù)時兰迫。
21. LazyForEach的工作原理是什么?
LazyForEach 的工作原理通常是基于用戶的滾動位置來動態(tài)地創(chuàng)建和銷毀列表項的組件實例炬称。當(dāng)用戶滾動到列表的某個部分時汁果,LazyForEach 會加載并渲染那些即將進(jìn)入視圖的列表項,同時可能會卸載那些滾出視圖的列表項玲躯,以節(jié)省內(nèi)存和計算資源据德。
22. Router.replace()方法的作用是什么?和Router.pushUrl()方法有什么區(qū)別跷车?
Router.replace()方法用于替換當(dāng)前路由棘利,并將目標(biāo)路由壓入棧頂。與Router.pushUrl()方法不同朽缴,Router.replace()方法不會保留當(dāng)前路由善玫,而是直接替換掉當(dāng)前路由。
23. 如何實現(xiàn)應(yīng)用的沉浸式模式密强?
沉浸式模式是指應(yīng)用界面呈現(xiàn)出沉浸式的全屏模式茅郎,不留任何系統(tǒng)UI,用戶只能看到應(yīng)用內(nèi)容或渤。在沉浸式模式下系冗,應(yīng)用的UI元素會被覆蓋,但系統(tǒng)狀態(tài)欄劳坑、導(dǎo)航欄毕谴、鍵盤等系統(tǒng)UI依然可見。以下是實現(xiàn)步驟
設(shè)置窗口屬性: 在應(yīng)用的入口Ability中,可以通過設(shè)置窗口屬性來實現(xiàn)沉浸式模式涝开。這通常涉及到配置窗口特性(Window Features)來隱藏狀態(tài)欄和導(dǎo)航欄循帐。
使用系統(tǒng)API: 鴻蒙OS提供了API來控制系統(tǒng)UI的顯示和隱藏。你可以在應(yīng)用的代碼中調(diào)用這些API來實現(xiàn)沉浸式效果舀武。
配置應(yīng)用的配置文件: 在應(yīng)用的config.json或其他配置文件中拄养,可以聲明應(yīng)用需要的窗口特性,如ohos:immersive银舱。
動態(tài)切換: 應(yīng)用可以根據(jù)用戶的交互或特定場景動態(tài)地進(jìn)入或退出沉浸式模式瘪匿。這可能涉及到監(jiān)聽用戶的手勢或其他事件來切換UI狀態(tài)。
適配不同設(shè)備: 不同的設(shè)備可能有不同的屏幕和系統(tǒng)UI寻馏,因此在實現(xiàn)沉浸式模式時棋弥,需要考慮不同設(shè)備的適配問題。
24. 如何獲取屏幕的安全區(qū)域?
可以通過設(shè)置組件的expandSafeArea屬性來獲取獲取UIWindow:首先诚欠,你需要獲取到當(dāng)前頁面的UIWindow實例顽染。
調(diào)用getSafeArea方法:通過UIWindow實例調(diào)用getSafeArea方法來獲取安全區(qū)域的Rect對象。 示例:
importohos.aafwk.ability.AbilitySlice;
importohos.aafwk.content.Intent;
importohos.agp.window.UIWindow;
importohos.agp.utils.Rect;
publicclassMyAbilitySliceextendsAbilitySlice{
@Override
publicvoidonStart(Intentintent) {
super.onStart(intent);
setUIContent(newSurfaceLayout(this));
UIWindowwindow=getUIWindow();
if(window!=null) {
// 獲取安全區(qū)域
RectsafeArea=window.getSafeArea();
// 在這里可以使用safeArea對象轰绵,它包含了安全區(qū)域的位置和尺寸信息
// 例如粉寞,可以使用safeArea.left, safeArea.top, safeArea.right, safeArea.bottom
? ? ?? }
?? }
}
25. ArkTs是什么?
ArkTS是HarmonyOS優(yōu)選的主力應(yīng)用開發(fā)語言。保持了TypeScript的基本風(fēng)格左腔,同時通過規(guī)范定義強(qiáng)化開發(fā)期靜態(tài)檢查和分析唧垦,提升程序執(zhí)行穩(wěn)定性和性能。 ArkTS的主要特點(diǎn)包括:
靜態(tài)類型檢查:ArkTS在編譯時進(jìn)行類型檢查液样,這有助于在代碼運(yùn)行前發(fā)現(xiàn)和修復(fù)錯誤振亮,提高代碼的穩(wěn)定性和性能。
聲明式UI:ArkTS定義了聲明式UI描述蓄愁,允許開發(fā)者以更簡潔双炕、更自然的方式開發(fā)跨端應(yīng)用。
狀態(tài)管理:ArkTS提供了多維度的狀態(tài)管理機(jī)制撮抓,使得與UI相關(guān)聯(lián)的數(shù)據(jù)可以在組件內(nèi)使用妇斤,也可以在不同組件層級間傳遞,支持單向和雙向數(shù)據(jù)流丹拯。
渲染控制:ArkTS支持條件渲染站超、循環(huán)渲染和數(shù)據(jù)懶加載,允許開發(fā)者根據(jù)應(yīng)用的不同狀態(tài)渲染UI內(nèi)容乖酬。
兼容性:ArkTS兼容TS/JavaScript生態(tài)死相,開發(fā)者可以使用TS/JS進(jìn)行開發(fā)或復(fù)用已有代碼。
并發(fā)機(jī)制:ArkTS支持輕量化的并發(fā)機(jī)制咬像,允許開發(fā)者編寫并發(fā)代碼算撮,提高應(yīng)用的性能和響應(yīng)速度生宛。
26. ArkTs與TypeScript有什么區(qū)別?(答5點(diǎn)以上)
ArkTS 是基于 TypeScript 開發(fā)的框架,但是有一些限制和差異肮柜。ArkTS 旨在提供更嚴(yán)格的類型檢查和優(yōu)化的代碼性能陷舅,同時確保與 HarmonyOS 的開發(fā)環(huán)境和特性兼容。以下是 ArkTS 與 TypeScript 的差異:
不支持使用對象字面量聲明類型审洞。
不支持使用 var關(guān)鍵字莱睁。
不支持使用 in運(yùn)算符。
不支持導(dǎo)入斷言芒澜。
不支持使用 any類型仰剿。
不支持使用 import賦值表達(dá)式。
不支持使用 require導(dǎo)入
具體區(qū)別:
生成器函數(shù):ArkTS 不支持 TypeScript 中的生成器函數(shù)(使用 function* 定義的函數(shù))痴晦,應(yīng)使用 async 或 await 機(jī)制進(jìn)行并行任務(wù)處理 南吮。
參數(shù)解構(gòu):在函數(shù)參數(shù)中使用解構(gòu)賦值是 TypeScript 的特性,ArkTS 不支持參數(shù)解構(gòu)阅酪,需要顯式傳遞參數(shù) 旨袒。
函數(shù)內(nèi)聲明函數(shù):TypeScript 允許在函數(shù)內(nèi)部聲明新的函數(shù),而 ArkTS 不支持在函數(shù)內(nèi)聲明函數(shù)术辐,應(yīng)使用 箭頭 函數(shù)代替 。
new.target:ArkTS 不支持 new.target 元屬性施无,這是 TypeScript 中用于反射的屬性 辉词。
確定賦值斷言:TypeScript 中的 ! 確定賦值斷言在 ArkTS 中不被支持,應(yīng)初始化變量或使用其他方式確保賦值 猾骡。
原型上的賦值:ArkTS 不支持在對象的原型上進(jìn)行賦值瑞躺,這與 TypeScript 不同 。
globalThis:ArkTS 不支持 globalThis兴想,這是 TypeScript 中用于獲取全局對象的屬性 幢哨。
Function.prototype.apply、Function.prototype.call 和 Function.prototype.bind:ArkTS 不支持這些函數(shù)嫂便,它們在 TypeScript 中用于控制函數(shù)的 this 綁定 捞镰。
instanceof 和 as 類型保護(hù):ArkTS 不支持 is 運(yùn)算符,必須使用 instanceof 運(yùn)算符替代毙替,并且在使用之前岸售,必須使用 as 運(yùn)算符將對象轉(zhuǎn)換為需要的類型 。
接口繼承類:在 TypeScript 中厂画,接口可以繼承類凸丸,但在 ArkTS 中,接口只能繼承接口 袱院。
構(gòu)造函數(shù)類型:ArkTS 不支持使用構(gòu)造函數(shù)類型屎慢,應(yīng)改用 箭頭函數(shù) 瞭稼。
enum 聲明合并:ArkTS 不支持 enum 聲明合并,所有相關(guān)的枚舉成員必須在同一個聲明中 腻惠。
命名空間作為對象:ArkTS 不支持將命名空間用作對象环肘,可以使用類或模塊替代 。
非聲明語句在命名空間中:ArkTS 中妖枚,命名空間用于定義標(biāo)志符可見范圍廷臼,不支持命名空間中的非聲明語句 。
import default as ...:ArkTS 不支持 import default as ... 語法绝页,應(yīng)使用顯式的 import ... from ... 語法 荠商。
require 和 import 賦值表達(dá)式:ArkTS 不支持通過 require 導(dǎo)入,也不支持 import 賦值表達(dá)式续誉,應(yīng)使用 import 語法 莱没。
ambient 模塊聲明:ArkTS 不支持 declare module 語法,應(yīng)直接導(dǎo)入需要的內(nèi)容 酷鸦。
new.target:ArkTS 不支持 new.target 元屬性饰躲,這是 TypeScript 中用于反射的屬性 。
Function.prototype.apply臼隔、Function.prototype.call 和 Function.prototype.bind:ArkTS 不支持這些函數(shù)嘹裂,它們在 TypeScript 中用于控制函數(shù)的 this 綁定 。
as const 斷言:ArkTS 不支持 as const 斷言摔握,這是 TypeScript 中用于標(biāo)注字面量的相應(yīng)字面量類型的語法 寄狼。
any:ArkTS 不支持any類型, 應(yīng)使用更具體的類型替代 。
27. @Provider和@Consumer vs @Provide和@Consume的區(qū)別氨淌?
能力V2 裝飾器@Provider 和@ConsumerV1 裝飾器@Provide 和@Consume
本地初始化允許本地初始化泊愧,當(dāng)找不到@Provider 的時候使用本地默認(rèn)值闺阱。禁止本地初始化稍味,當(dāng)找不到對應(yīng)的@Provide 時候,會拋出異常奶赔。
支持類型支持 function豪筝。不支持 function痰滋。
觀察能力僅能觀察自身賦值變化,如果要觀察嵌套場景壤蚜,配合@Trace 一起使用即寡。觀察第一層變化,如果要觀察嵌套場景袜刷,配合@Observed 和@ObjectLink 一起使用聪富。
alias 和屬性名alias 是唯一匹配的 key,如果缺省 alias著蟹,則默認(rèn)屬性名為 alias墩蔓。alias 和屬性名都為 key梢莽,優(yōu)先匹配 alias,匹配不到可以匹配屬性名奸披。
從父組件初始化禁止昏名。允許。
支持重載默認(rèn)開啟阵面,即@Provider 可以重名轻局,@Consumer 向上查找最近的@Provider。默認(rèn)關(guān)閉样刷,即在組件樹上不允許有同名@Provide仑扑。如果需要重載,則需要配置 allowOverride置鼻。
28. @Prop和@ObjectLink裝飾器有什么區(qū)別镇饮?
1.用途
@Prop裝飾器:主要用于在組件之間傳遞數(shù)據(jù),將父組件的值傳遞給子組件箕母。它定義了子組件的屬性储藐,可以接收來自父組件的賦值。@ObjectLink用于建立對象之間的鏈接嘶是,通常用于在組件內(nèi)部或組件之間共享和同步狀態(tài)钙勃。它可以將一個對象的屬性與另一個對象的屬性進(jìn)行鏈接,當(dāng)一個對象的屬性發(fā)生變化時聂喇,另一個對象的屬性也會自動更新肺缕。
數(shù)據(jù)傳遞方式
@Prop:是單向的數(shù)據(jù)傳遞,從父組件到子組件授帕。父組件可以設(shè)置子組件的 @Prop屬性值,但子組件不能直接修改這個值浮梢。@ObjectLink是雙向的數(shù)據(jù)傳遞跛十,父組件和子組件都可以修改子組件的 @ObjectLink屬性值。
性能
@Prop會深拷貝數(shù)據(jù)秕硝,具有拷貝的性能開銷芥映,性能低于 @ObjectLink詳見官方文檔。
29. ForEach和LazyForEach的區(qū)別远豺?
ForEach和LazyForEach都是用于渲染列表的裝飾器奈偏,它們的區(qū)別在于:
ForEach:渲染列表時,會將列表中的每一項都渲染一次躯护,適用于列表項數(shù)量較少的情況惊来。
LazyForEach:渲染列表時,只渲染當(dāng)前可見的列表項棺滞,適用于列表項數(shù)量較多的情況裁蚁。
30. UIAbility的生命周期有哪些矢渊?
UIAbility的生命周期包括Create、Foreground枉证、Background矮男、Destroy四個狀態(tài),如下圖所示室谚。
!外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c9592a651b9a4708a680802f87e2879d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5YmN56uv6L2s5YWo5qCIaW5n:q75.awebp?rk3s=f64ab15b&x-expires=1732157407&x-signature=dnMJ11r1gRcTFRXwYBy1Cd1LD5Y%3D)
31. H5如何與HarmonyOS應(yīng)用(webView)進(jìn)行通信毡鉴?官方文檔
應(yīng)用側(cè)調(diào)用前端頁面JS函數(shù)
應(yīng)用側(cè)可以通過runJavaScript()方法異步調(diào)用前端頁面的JavaScript相關(guān)函數(shù),并通過Promise方式返回腳本執(zhí)行的結(jié)果秒赤。runJavaScript需要在loadUrl完成后猪瞬,比如onPageEnd中調(diào)用。
前端頁面調(diào)用應(yīng)用側(cè)函數(shù)
使用Web組件將應(yīng)用側(cè)代碼注冊到前端頁面中倒脓,注冊完成之后撑螺,前端頁面中使用注冊的對象名稱就可以調(diào)用應(yīng)用側(cè)的函數(shù),實現(xiàn)在前端頁面中調(diào)用應(yīng)用側(cè)方法崎弃。注冊應(yīng)用側(cè)代碼有兩種方式甘晤,一種在Web組件初始化調(diào)用,使用javaScriptProxy()接口饲做。另外一種在Web組件初始化完成后調(diào)用线婚,使用registerJavaScriptProxy()接口。
32. 如何實現(xiàn)圖片上傳?
有兩種方式原生和Web組件:
原生:使用上傳下載模塊(ohos.request)的上傳接口將本地文件(圖片)上傳盆均,需聲明權(quán)限:ohos.permission.INTERNET塞弊。 代碼示例:
// pages/xxx.ets
import{common}from'@kit.AbilityKit';
importfsfrom'@ohos.file.fs';
import{BusinessError,request}from'@kit.BasicServicesKit';
// 獲取應(yīng)用文件路徑
letcontext=getContext(this)ascommon.UIAbilityContext;
letcacheDir=context.cacheDir;
// 新建一個本地應(yīng)用文件
letfile=fs.openSync(cacheDir+'/test.txt',fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE);
fs.writeSync(file.fd,'upload file test');
fs.closeSync(file);
// 上傳任務(wù)配置項
letheader=newMap<Object,string>();
header.set('key1','value1');
header.set('key2','value2');
letfiles:Array<request.File>=[
//uri前綴internal://cache 對應(yīng)cacheDir目錄
{filename:'test.txt',name:'test',uri:'internal://cache/test.txt',type:'txt'}
]
letdata:Array<request.RequestData>=[{name:'name',value:'value'}];
letuploadConfig:request.UploadConfig={
url:'https://xxx',
header:header,
method:'POST',
files:files,
data:data
}
// 將本地應(yīng)用文件上傳至網(wǎng)絡(luò)服務(wù)器
try{
request.uploadFile(context,uploadConfig)
.then((uploadTask:request.UploadTask)=>{
uploadTask.on('complete', (taskStates:Array<request.TaskState>)=>{
for(leti=0;i<taskStates.length;i++) {
console.info(`upload complete taskState: ${JSON.stringify(taskStates[i])}`);
? ? ?? }
? ?? });
?? })
.catch((err:BusinessError)=>{
console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
?? })
}catch(error) {
leterr:BusinessError=errorasBusinessError;
console.error(`Invoke uploadFile failed, code is ${err.code}, message is ${err.message}`);
}
使用axios上傳:使用axios上傳文件,需安裝axios依賴泪姨。 注意事項
上傳文件需要單獨(dú)導(dǎo)入FormData模塊
當(dāng)前版本只支持 Stage 模型
上傳類型支持uri和ArrayBuffer游沿,uri支持“internal”協(xié)議類型和沙箱路徑,僅支持"internal"協(xié)議類型肮砾,"internal://cache/"為必填字段诀黍,示例: internal://cache/path/to/file.txt;沙箱路徑示例:cacheDir + '/hello.txt'
請求的表單數(shù)據(jù)值為string類型
支持設(shè)置多部分表單數(shù)據(jù)的數(shù)據(jù)名稱和數(shù)據(jù)類型類型
上傳參數(shù)context:當(dāng)uri為沙箱路徑,無需傳參context仗处;若uri為“internal”協(xié)議類型眯勾,必須傳參context
當(dāng)上傳的內(nèi)容為ArrayBuffer時,用法如下
importaxiosfrom'@ohos/axios'
import{FormData}from'@ohos/axios'
importfsfrom'@ohos.file.fs';
// ArrayBuffer
letformData=newFormData()
letcacheDir=getContext(this).cacheDir
try{
// 寫入
letpath=cacheDir+'/hello.txt';
letfile=fs.openSync(path,fs.OpenMode.CREATE|fs.OpenMode.READ_WRITE)
fs.writeSync(file.fd,"hello, world");// 以同步方法將數(shù)據(jù)寫入文件
fs.fsyncSync(file.fd);// 以同步方法同步文件數(shù)據(jù)婆誓。
fs.closeSync(file.fd);
// 讀取
letfile2=fs.openSync(path,0o2);
letstat=fs.lstatSync(path);
letbuf2=newArrayBuffer(stat.size);
fs.readSync(file2.fd,buf2);// 以同步方法從流文件讀取數(shù)據(jù)吃环。
fs.fsyncSync(file2.fd);
fs.closeSync(file2.fd);
formData.append('file',buf2);
// formData.append('file', buf2, { filename: 'text.txt', type: 'text/plain'}); 設(shè)置多部分表單數(shù)據(jù)的數(shù)據(jù)名稱和數(shù)據(jù)類型類型
}catch(err) {
console.info('err:'+JSON.stringify(err));
}
// 發(fā)送請求
axios.post<string,AxiosResponse<string>,FormData>(this.uploadUrl,formData, {
headers: {'Content-Type':'multipart/form-data'},
context:getContext(this),
onUploadProgress: (progressEvent:AxiosProgressEvent):void=>{
console.info(progressEvent&&progressEvent.loaded&&progressEvent.total?Math.ceil(progressEvent.loaded/progressEvent.total*100)+'%':'0%');
},
}).then((res:AxiosResponse)=>{
console.info("result"+JSON.stringify(res.data));
}).catch((error:AxiosError)=>{
console.error("error:"+JSON.stringify(error));
})
當(dāng)上傳的uri時,用法如下
importaxiosfrom'@ohos/axios'
import{FormData}from'@ohos/axios'
letformData=newFormData()
formData.append('file','internal://cache/blue.jpg')
// formData.append('file', cacheDir + '/hello.txt'); uri支持傳入沙箱路徑
// 發(fā)送請求
axios.post<string,AxiosResponse<string>,FormData>('https://www.xxx.com/upload',formData, {
headers: {'Content-Type':'multipart/form-data'},
context:getContext(this),
onUploadProgress: (progressEvent:AxiosProgressEvent):void=>{
console.info(progressEvent&&progressEvent.loaded&&progressEvent.total?Math.ceil(progressEvent.loaded/progressEvent.total*100)+'%':'0%');
? },
}).then((res:AxiosResponse<string>)=>{
console.info("result"+JSON.stringify(res.data));
}).catch((err:AxiosError)=>{
console.error("error:"+JSON.stringify(err));
})
33.hap洋幻、har郁轻、hsp三者的區(qū)別?
HAP(Harmony Ability Package)是應(yīng)用安裝和運(yùn)行的基本單元。HAP包是由代碼鞋屈、資源范咨、第三方庫故觅、配置文件等打包生成的模塊包,其主要分為兩種類型:entry和feature渠啊。(又稱ability)
HAR(Harmony Archive)是靜態(tài)共享包输吏,可以包含代碼、C++庫替蛉、資源和配置文件贯溅。通過HAR可以實現(xiàn)多個模塊或多個工程共享ArkUI組件、資源等相關(guān)代碼躲查。(又稱static library, 靜態(tài)共享包)
HSP(Harmony Shared Package)是動態(tài)共享包它浅,可以包含代碼、C++庫镣煮、資源和配置文件姐霍,通過HSP可以實現(xiàn)代碼和資源的共享。HSP不支持獨(dú)立發(fā)布典唇,而是跟隨其宿主應(yīng)用的APP包一起發(fā)布镊折,與宿主應(yīng)用同進(jìn)程,具有相同的包名和生命周期介衔。(又稱shared library, 動態(tài)共享包)
34. 鴻蒙常用的裝飾器有哪些恨胚?
@State 定義狀態(tài),當(dāng)前組件能使用
@Prop 父子組件通信(特點(diǎn):子組件數(shù)據(jù)不能修改)
@Link 父子組件通信(特點(diǎn):子組件數(shù)據(jù)可以修改)
@Observed 和 @ObjectLink 父子組件通信(特點(diǎn):嵌套第二層數(shù)據(jù)修改可以達(dá)到響應(yīng)式炎咖,之前方案不行)
@Provide 和 @Consume 祖孫組件通信
@Builder 和 @BuilderParam 父子組件通信赃泡,通信組件數(shù)據(jù)
@Watch 監(jiān)視數(shù)據(jù)的變化(第一次不會觸發(fā))
35. 如何啟動一個 ability?
通過 context 對象的 startAbility 方法官方文檔:
import{common,Want}from'@kit.AbilityKit';
import{BusinessError}from'@kit.BasicServicesKit';
context=getContext(this)ascommon.UIAbilityContext;// UIAbilityContext
constwant:Want={
deviceId:'',// deviceId為空表示本設(shè)備
bundleName:'com.example.system',// AppScope/app.json5 中找
abilityName:'SecondAbility',// 去對應(yīng)的ability內(nèi)部找module.json5
// moduleName: 'entry' // moduleName非必選
parameters: {// 攜帶參數(shù)
? }
};
this.context.startAbility(want, (err:BusinessError)=>{
if(err.code) {
// 顯式拉起Ability,通過bundleName乘盼、abilityName和moduleName可以唯一確定一個Ability
console.error(`Failed to startAbility. Code: ${err.code}, message: ${err.message}`);
? }
});
36. 顯示 want 和 隱式 want 的區(qū)別?
顯式Want:在啟動目標(biāo)應(yīng)用組件時升熊,調(diào)用方傳入的want參數(shù)中指定了abilityName和bundleName,稱為顯式Want绸栅。 顯式Want通常用于應(yīng)用內(nèi)組件啟動僚碎,通過在Want對象內(nèi)指定本應(yīng)用Bundle名稱信息(bundleName)和abilityName來啟動應(yīng)用內(nèi)目標(biāo)組件。當(dāng)有明確處理請求的對象時阴幌,顯式Want是一種簡單有效的啟動目標(biāo)應(yīng)用組件的方式。 例如:打開其他窗口
隱式Want:在啟動目標(biāo)應(yīng)用組件時卷中,調(diào)用方傳入的want參數(shù)中未指定abilityName矛双,稱為隱式Want。 當(dāng)需要處理的對象不明確時蟆豫,可以使用隱式Want议忽,在當(dāng)前應(yīng)用中使用其他應(yīng)用提供的某個能力,而不關(guān)心提供該能力的具體應(yīng)用十减。隱式Want使用skills標(biāo)簽來定義需要使用的能力栈幸,并由系統(tǒng)匹配聲明支持該請求的所有應(yīng)用來處理請求愤估。例如,需要打開一個鏈接的請求速址,系統(tǒng)將匹配所有聲明支持該請求的應(yīng)用玩焰,然后讓用戶選擇使用哪個應(yīng)用打開鏈接。 例如:將pdf文件傳遞給其他應(yīng)用窗口 總的來說
顯示want和隱式want的區(qū)別在于有無abilityName芍锚。有就是顯示want昔园,沒有就是隱式want
顯示want主要用于當(dāng)前應(yīng)用窗口跳轉(zhuǎn),隱式want打開其他應(yīng)用的窗口
37. 三層架構(gòu)是什么并炮?
官方文檔 三層架構(gòu)為了“一次開發(fā)默刚,多端部署”,項目結(jié)構(gòu)采用三層架構(gòu) 三層工程結(jié)構(gòu)如下:
commons(公共能力層):用于存放公共基礎(chǔ)能力集合(如工具庫逃魄、公共配置等)荤西。commons層可編譯成一個或多個HAR包或HSP包,只可以被products和features依賴伍俘,不可以反向依賴邪锌。
features(基礎(chǔ)特性層):開發(fā)頁面、組件(HAR包或HSP包)养篓。
products(產(chǎn)品定制層):定義phone\pad兩個ability秃流,引用 features 的包和 commons 的包完成應(yīng)用功能
38. 優(yōu)化內(nèi)存有哪些方法?
使用onMemoryLevel監(jiān)聽內(nèi)存變化
等級值說明
MEMORY_LEVEL_MODERATE0系統(tǒng)內(nèi)存適中柳弄。系統(tǒng)可能會開始根據(jù) LRU 緩存規(guī)則殺死進(jìn)程舶胀。
MEMORY_LEVEL_LOW1系統(tǒng)內(nèi)存比較低。此時應(yīng)該去釋放掉一些不必要的資源以提升系統(tǒng)的性能碧注。
MEMORY_LEVEL_CRITICAL2系統(tǒng)內(nèi)存很低嚣伐。此時應(yīng)當(dāng)盡可能地去釋放任何不必要的資源,因為系統(tǒng)可能會殺掉所有緩存中的進(jìn)程萍丐,并且開始?xì)⒌魬?yīng)當(dāng)保持運(yùn)行的進(jìn)程轩端,比如后臺運(yùn)行的服務(wù)。
使用LRUCache優(yōu)化ArkTS內(nèi)存 例如:我們搜索租房列表可以無限加載租房數(shù)據(jù)逝变,這樣數(shù)據(jù)會越來越多基茵,我們使用LRUCacheUtil來管理數(shù)據(jù)
使用生命周期管理優(yōu)化ArkTS內(nèi)存 例如:aboutToDisappear中銷毀訂閱事件,清除定時器等 4.使用purgeable優(yōu)化C++內(nèi)存
39. 多線程實現(xiàn)方式TaskPoll和Worker的區(qū)別?
TaskPool和Worker均支持多線程并發(fā)能力壳影。由于TaskPool的工作線程會綁定系統(tǒng)的調(diào)度優(yōu)先級拱层,并且支持負(fù)載均衡(自動擴(kuò)縮容),而Worker需要開發(fā)者自行創(chuàng)建宴咧,存在創(chuàng)建耗時以及不支持設(shè)置調(diào)度優(yōu)先級根灯,故在性能方面使用TaskPool會優(yōu)于Worker,因此大多數(shù)場景推薦使用TaskPool。
TaskPool偏向獨(dú)立任務(wù)維度烙肺,該任務(wù)在線程中執(zhí)行纳猪,無需關(guān)注線程的生命周期,超長任務(wù)(大于3分鐘且非長時任務(wù))會被系統(tǒng)自動回收桃笙;而Worker偏向線程的維度氏堤,支持長時間占據(jù)線程執(zhí)行,需要主動管理線程生命周期怎栽。
40. 音視頻的組件的使用方式?
視頻組件 Video
controller:VideoController=newVideoController()
Video({
src:$rawfile('test.mp4'),
previewUri:$r('app.media.startIcon'),
controller:this.controller
})
.width('100%')
.height(200)
.autoPlay(true)
.controls(true)
音頻組件 Audio 官方文檔(了解)
//配置音頻渲染參數(shù)并創(chuàng)建AudioRenderer實例丽猬,音頻渲染參數(shù)的詳細(xì)信息可以查看AudioRendererOptions。
import{audio}from'@kit.AudioKit';
letaudioStreamInfo:audio.AudioStreamInfo={
samplingRate:audio.AudioSamplingRate.SAMPLE_RATE_48000,// 采樣率
channels:audio.AudioChannel.CHANNEL_2,// 通道
sampleFormat:audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,// 采樣格式
encodingType:audio.AudioEncodingType.ENCODING_TYPE_RAW// 編碼格式
};
letaudioRendererInfo:audio.AudioRendererInfo={
usage:audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION,
rendererFlags:0
};
letaudioRendererOptions:audio.AudioRendererOptions={
streamInfo:audioStreamInfo,
rendererInfo:audioRendererInfo
};
audio.createAudioRenderer(audioRendererOptions, (err,data)=>{
if(err) {
console.error(`Invoke createAudioRenderer failed, code is ${err.code}, message is ${err.message}`);
return;
}else{
console.info('Invoke createAudioRenderer succeeded.');
letaudioRenderer=data;
? }
});
// 調(diào)用on('writeData')方法熏瞄,訂閱監(jiān)聽音頻數(shù)據(jù)寫入回調(diào)脚祟。
import{BusinessError}from'@kit.BasicServicesKit';
import{fileIo}from'@kit.CoreFileKit';
letbufferSize:number=0;
classOptions{
offset?:number;
length?:number;
}
letpath=getContext().cacheDir;
//確保該路徑下存在該資源
letfilePath=path+'/StarWars10s-2C-48000-4SW.wav';
letfile:fileIo.File=fileIo.openSync(filePath,fileIo.OpenMode.READ_ONLY);
letwriteDataCallback=(buffer:ArrayBuffer)=>{
letoptions:Options={
offset:bufferSize,
length:buffer.byteLength
? }
fileIo.readSync(file.fd,buffer,options);
bufferSize+=buffer.byteLength;
}
audioRenderer.on('writeData',writeDataCallback);
//調(diào)用start()方法進(jìn)入running狀態(tài),開始渲染音頻强饮。
import{BusinessError}from'@kit.BasicServicesKit';
audioRenderer.start((err:BusinessError)=>{
if(err) {
console.error(`Renderer start failed, code is ${err.code}, message is ${err.message}`);
}else{
console.info('Renderer start success.');
? }
});
//調(diào)用stop()方法停止渲染由桌。
import{BusinessError}from'@kit.BasicServicesKit';
audioRenderer.stop((err:BusinessError)=>{
if(err) {
console.error(`Renderer stop failed, code is ${err.code}, message is ${err.message}`);
}else{
console.info('Renderer stopped.');
? }
});
// 調(diào)用release()方法銷毀實例,釋放資源邮丰。
import{BusinessError}from'@kit.BasicServicesKit';
audioRenderer.release((err:BusinessError)=>{
if(err) {
console.error(`Renderer release failed, code is ${err.code}, message is ${err.message}`);
}else{
console.info('Renderer released.');
? }
});
41. 上拉加載和下拉刷新如何實現(xiàn)?
典型場景與實現(xiàn)方案行您、下拉刷新與上拉加載、如何實現(xiàn)List/Swiper/Grid嵌套滾動的下拉刷新和上拉加載更多
上拉加載: 使用pullToRefresh組件可以實現(xiàn)上拉加載更多數(shù)據(jù)的效果 剪廉。該組件支持懶加載娃循,可以通過設(shè)置LazyForEach來實現(xiàn)數(shù)據(jù)的按需加載 。 在使用pullToRefresh組件時斗蒋,需要將列表組件捌斧、綁定的數(shù)據(jù)對象和scroller對象包含進(jìn)去,并添加上滑方法泉沾。
下拉刷新: 可以使用Refresh組件來實現(xiàn)下拉刷新功能 捞蚂。刷新邏輯可以在onRefreshing回調(diào)方法中執(zhí)行。 當(dāng)列表滑動到底部時跷究,可以觸發(fā)onReachEnd事件回調(diào)姓迅,用于加載更多數(shù)據(jù) 。 這些組件和方法可以幫助開發(fā)者在鴻蒙(HarmonyOS)中實現(xiàn)流暢的上拉加載和下拉刷新功能俊马,提升用戶體驗丁存。