HarmonyOS 應用模塊化設計 - 面試核心知識點
在 HarmonyOS 開發面試中,模塊化設計是必考知識點。本文從面試官角度深度解析 HarmonyOS 應用模塊化設計,涵蓋 HAP、HAR、HSP 等核心概念,助你輕松應對技術面試!
🎯 面試高頻問題:什么是模塊化設計?
面試官常問:請解釋 HarmonyOS 應用模塊化設計的核心理念?
標準答案:
在大型軟件工程中,模塊化設計是現代軟件工程的核心原則之一。通過將大型復雜系統拆解為更小、更易管理和理解的功能模塊,提高系統的可維護性和可擴展性。
核心特點:
- 多團隊弱耦合協作開發
- 契約化接口定義業務交互
- 各團隊業務獨立發展,互不影響
- 支持快速迭代演進
在 HarmonyOS 中的體現:
- 模塊化既是設計原則,也是開發實踐
- 將應用程序拆分為多個功能模塊
- 每個模塊負責特定功能或特性
- 支持獨立開發、編譯和部署
- 可在不同設備上靈活組合和調用
📋 面試重點一:應用程序包結構
面試官:HarmonyOS 的應用包結構有哪些類型?
回答要點:
在進行模塊化設計時,需要考慮 HarmonyOS 的應用包結構選型:
- 開發態:源碼組織方式
- 編譯態:編譯過程中的包形態
- 發布態:最終發布的應用包結構
關鍵概念:
- HAP:HarmonyOS Ability Package
- HAR:HarmonyOS Archive
- HSP:HarmonyOS Shared Package
📋 面試重點二:Ability 應用組件設計
面試官:在多設備場景下,如何設計 Ability 組件?
🔥 面試要點 1:多任務多窗口場景
手機設備應用場景:
// 筆記應用 - 多頁面復制場景
// 文檔編輯應用 - 多文檔同時編輯
// 導航應用 - 后臺運行 + 主頁查找
// 購物應用 - 客服界面快速切換
// 支付應用 - 信息查找復制
實際應用示例:
- 筆記應用:可讓用戶將信息從筆記的一頁復制到另一頁
- 文檔編輯應用:可讓用戶同時打開編輯多個文檔,可讓用戶將內容從一個文檔復制或移動到另一個文檔
- 導航/打車應用:可以讓導航后臺運行,回到主頁查找新的位置信息或其它信息
- 購物類臨時客服界面:可讓用戶通過任務管理快速從商品瀏覽頁切換回到客服會話界面,避免用戶一層層打開查找
- 在應用支付/登錄頁面:用戶可以切換到其他頁面查找并復制相關信息
大屏設備應用場景:
// 視頻播放器 - 播放 + 瀏覽列表
// 電子郵件 - 撰寫 + 查看收件箱
// 地址簿 - 并排比較聯系信息
// 閱讀應用 - 多篇文章同時打開
實際應用示例:
- 視頻播放器應用:可讓用戶在觀看播放內容的同時瀏覽其他可能感興趣的視頻列表
- 電子郵件應用:可讓用戶在撰寫電子郵件的同時查看收到的郵件列表
- 地址簿應用:可讓用戶并排比較多個人員的聯系信息
- 閱讀應用:可讓用戶在查閱所有標題概要后,打開多篇文章供稍后閱讀
🔥 面試要點 2:Ability 設計原則
單 Ability 情況:
- 單窗口類型應用
- 多實例或指定實例的多任務應用
- 普通游戲應用建議采用單 HAP 承載 UIAbility
多 Ability 情況:
-
多窗口類型應用
- 每個窗口對應不同功能
- 通過不同的 UIAbility 承載
- 可設計為 Feature 類型的 HAP
-
應用擴展功能
- 卡片和分享業務
- 由系統提供的 ExtensionAbility 承載
- 建議通過 Feature 類型的 HAP 承載
📋 面試重點三:應用模塊化選型
面試官:如何選擇合適的模塊類型?
💡 面試技巧:三種模塊類型對比
模塊類型 | 特點 | 使用場景 | 面試要點 |
---|---|---|---|
Entry HAP | 應用主入口,默認存在且唯一 | 應用啟動入口 | 每個應用必須有且僅有一個 |
Feature HAP | 獨立功能模塊,可按需加載 | 獨立功能、擴展能力 | 支持獨立安裝和運行 |
HAR | 靜態共享庫 | 代碼復用、跨應用共享 | 編譯時打包進目標模塊 |
HSP | 動態共享庫 | 按需加載、運行時共享 | 獨立安裝,運行時加載 |
🎯 面試加分項:三種業務場景分析
1. 共享模塊場景
圖 1 多工程合作模式
面試官:什么是共享模塊?
回答要點:
- 某個功能模塊需要在多個應用之間共享代碼邏輯和資源
- 通過公司私有的 OHPM 倉發布和集成編譯產物
- 支持多團隊代碼倉隔離開發
- 只能使用 HAR 模塊實現
2. 按需加載模塊場景
面試官:按需加載模塊有什么優勢?
回答要點:
- 減少包體積:首次下載不包含按需加載模塊
- 減少系統資源:節省 ROM 和 RAM 空間
- 架構演進:模塊間耦合關系清晰
技術選型:
- Feature 類型的 HAP:可包含 Ability 組件
- HSP:不包含 Ability 組件的按需加載
場景劃分:
- 單 HAP 場景:只包含一個 UIAbility 組件,優先采用單 HAP(Entry 類型的 HAP)來實現應用開發
- 多 HAP 場景:要實現多任務承載多個 UIAbility 組件以及使用 ExtensionAbility 組件實現擴展功能
3. 多 HAP/HSP 引用相同 HAR 包的影響
圖 2 HAP 包和 HSP 包分別引用相同 HAR 包
面試官:多模塊引用同一 HAR 包會有什么問題?
回答要點:
- 破壞 HAR 的單例模式
- 導致方法在多個模塊中重復執行
- 增加應用冷啟動時間
技術原理:
工程內包含三個模塊:HAP 包作為應用主入口模塊,HSP 包作為應用主界面顯示模塊,HAR_COMMON 集成了所有通用工具類,其中 funcResult 是 func 方法的執行結果。
當 HAP 和 HSP 模塊同時引用 HAR_COMMON 模塊時,會破壞 HAR 的單例模式。因此,HAP 和 HSP 模塊在使用 HAR_COMMON 中的 funcResult 時,會導致 func 方法在兩個模塊加載時各執行一次,從而增加文件的執行時間。
優化方案:
圖 3 切換為 HAP 包和 HAR 包分別引用相同 HAR 包
優化建議:
- 在多 HAP/HSP 引用相同 HAR 包的情況下,如果 HSP 包和 HAR 包均能滿足業務需求,建議將 HSP 包改為 HAR 包
- 若使用的 HSP 為集成態 HSP,可跳過該優化方案
性能測試代碼示例:
// 1. 在被引用 HAR_COMMON 包中寫入功能示例
// 2. 分別通過使用 HSP 包和 HAR 包來引用該 HAR_COMMON 包中的功能進行性能對比實驗// 使用 HAP 包和 HSP 包引用該 HAR_COMMON 包中的功能
// HAP 包引用 HAR_COMMON 包中的功能// 使用 HAP 包和 HAR 包引用該 HAR_COMMON 包中的功能
// HAP 包引用 HAR_COMMON 包中的功能
性能分析:
使用 Launch 模板,對優化前后啟動性能進行對比分析。
分析階段的起點為啟動 Ability(即 H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility
的開始點),階段終點為應用第一次接到 vsync(即 H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int
的開始點)。
圖 4 優化前,使用 HSP 包
圖 5 優化后,使用 HAR 代替 HSP
性能對比數據:
方案 | 階段時長(毫秒) | 性能提升 |
---|---|---|
(優化前)使用 HSP 包 | 3125 | - |
(優化后)使用 HAR 代替 HSP | 853.9 | 73% ↑ |
說明:
上述示例為凸顯出差異,func 執行函數循環次數為 100000000,開發者實際修改后收益需根據實際情況測試。
測試數據表明,將 HSP 替換為 HAR 包后,應用啟動耗時明顯縮短。
📋 面試重點四:單 HAP 工程設計
面試官:單 HAP 工程如何進行模塊化設計?
🔥 面試要點 1:不包含按需加載模塊
圖 6 非按需加載工程模型
設計原則:
對于不需要按需加載且僅包含一個 Entry 類型的 HAP 的 App,可以直接全部采用 HAR 進行開發設計。
說明:
這里提到的"僅有一個 HAP"是指一種設備類型僅包含一個 HAP,而不是指.app 文件包中僅有一個 HAP。.app 文件包可以包含其他設備的 HAP 包,例如手表和大屏設備的 HAP 包,以支持多設備分發。
架構特點:
- 除產品模塊層的 HAP 外,其他模塊均為 HAR
- 所有 HAR 最終編譯進 HAP 中
優點:
- 無額外 HSP,節省安裝和加載成本
- 利用 ArkTS 語言特性和編譯器優化
- 代碼工程架構簡單,演進靈活
🔥 面試要點 2:包含按需加載模塊
面試官:如何在單 HAP 工程中實現按需加載?
技術選型考慮:
在單 HAP 工程中實現按需加載功能時,對應的組件需采用 HSP 作為按需加載模塊。HAR 是靜態共享庫,若多個 HAP 或 HSP 依賴同一份 HAR,該 HAR 在應用內會被重復存儲。HSP 是動態共享庫,其安裝和加載會有性能損失,過多的 HSP 可能影響安裝效率和 App 啟動性能。需考慮 App 占用空間是否受限及啟動性能的敏感度,根據業務需求在 App Size 與啟動性能之間做好平衡。
說明:
這里提到的 App Size 指用戶安裝按需加載模塊后,應用的整體大小。
App Size 優先方案:
圖 7 公共依賴模塊通過 HSP 模塊殼承載
設計思路:
對于 App Size 優先的,可以考慮將公共依賴的模塊封裝在一個 HSP 模塊殼中。
// 模塊依賴關系示例
// hap_A 依賴:har_A + har_C + har_D
// hsp_B 依賴:har_B + har_C + har_D
// 解決方案:將 har_C 和 har_D 封裝到 common_hsp 中
實現方案:
hap_A 依賴于獨有的共享庫 har_A,同時需要依賴于 har_C 和 har_D;而按需加載模塊 hsp_B 依賴于獨有的共享庫 har_B,同時需要依賴于 har_C 和 har_D。
說明:
這里的共享庫 har_A、har_B、har_C、har_D 不一定本地工程,有可能是從 ohpm 倉上依賴下載的。
因為 har_C 和 har_D 同時被 hap_A 和 hsp_B 工程所依賴,所以為了節省 App Size,可以將其封裝到名為"common_hsp"的 Module 中,對外暴露 har_C 和 har_D 的接口,將 har_C 和 har_D 打包到 common_hsp 中,最后讓 hap_A 和 hsp_B 依賴于 common_hsp 工程。common_hsp 工程是無實際意義的,它僅是一個"模塊殼",是為了最小化 App Size 而存在的。
性能優先方案:
圖 8 公共依賴模塊使用 HAR 模塊承載
設計思路:
對于性能優先的,則不需要再封裝一個公共的 HSP 模塊,直接依賴公共 HAR 包。
因為公共 HSP 包需要安裝和加載,所以會有一些性能損耗。對于啟動性能敏感型的應用,則將 hap_A 和 hsp_B 直接依賴于 har_C 和 har_D。最終編譯產物里面有 2 個,hap_A.hap 和 hsp_B.hsp,但是這兩個編譯產物里面均會包含 har_C 和 har_D,App Size 會比采用公共 HSP 模型大。
📋 面試重點五:多 HAP 工程設計
面試官:多 HAP 工程的設計原則是什么?
💡 面試技巧:多 HAP 應用場景
適用場景:
對于同一個設備類型,如果要實現不同的獨立功能模塊,并且相對獨立,以及具有單獨的入口的功能特性,建議做成一個獨立特性的 HAP,按需下載安裝。
組成結構:
此時一個 App 包中,就會有多個 HAP 包,其中有且僅有一個 Entry 類型的 HAP,其他的均是 Feature 類型的 HAP。多 HAP 之間業務獨立,但是可能會有業務能力共享,所以在進行模塊化設計時,需要根據是否具有公共能力來進行選擇。
🔥 面試要點 1:包含公共能力模塊
面試官:多 HAP 工程如何處理公共能力模塊?
對于具備公共能力模塊的工程,和上述 HAP+HSP 組合是類似的,需要考慮在 App Size 與啟動性能之間做平衡。
性能優先方案:
圖 9 多 HAP 工程模塊示意圖
特點:
一般多 HAP 應用架構普適性采用以下模型,除了產品組件中存在 HAP 包之外,其余的均是 HAR 包。
編譯產物中,多個 HAP 之間存在相同的 HAR 包(如 har_2、har_3、har_C、har_D、har_E)。這種情況下,App Size 可能會增大。如果 App Size 不是應用的瓶頸,或者 HAR 包的大小較小,對 App Size 的影響可控,可以采用這種模型,從而減少動態加載的性能損耗。
App Size 優先方案:
圖 10 多 HAP 工程模塊示意圖
設計思路:
上述問題的本質在于如何在 HAP 和 HSP 之間分布 HAR 包,以最小化 App 的大小并減少 HAR 的重復編譯和打包。主要思路是將公共能力模塊封裝為公共 HSP,從而最小化 App Size。
?? 重要注意事項:
需要注意,在應用間共享的 HAR 包,原則上是不允許依賴 HSP 包,因為 HSP 包是專屬于應用,和 bundleName 進行了綁定,一旦 HAR 包依賴于應用內 HSP,該 HAR 包就丟失了共享性,無法再給其他應用共享。
實現方案:
如上圖所示,有 3 個 HAP 包(1 個 entry 和 2 個 feature),將公共的 HAR 包封裝到 HSP 工程中,例如 common_wrap_hsp 和 feature_wrap_hsp。
// 模塊殼設計示例
// common_wrap_hsp 和 feature_wrap_hsp 僅為模塊殼
// 用于合理放置模塊在編譯產物中的位置
// 不具備模塊功能,不能共享,僅能在 App 應用內使用
這兩個 HSP 從嚴格意義上講,不能稱為模塊,僅稱為模塊殼,用于合理放置模塊在編譯產物中的位置,不具備模塊功能,不能共享,僅能在 App 應用內使用,依賴這些模塊殼的模塊也無法在應用間共享。
上述的模型通過 HSP 將 HAR 包合理分配到編譯產物中,確保每個 HAR 包在 App 編譯產物中僅出現一次,從而減小 App Size。模塊殼數量不宜過多,否則可能影響安裝速度和啟動性能。
平衡方案:
這兩種模型都是理想模型,業務模型通常是兩者的平衡態或組合。例如,某個共享庫代碼和資源較少,占用空間較小,如打印日志模塊。將該模塊編譯進所有編譯產物中,App Size 增加較少,同時性能較好。
🔥 面試要點 2:不包含公共能力模塊
回答要點:
這種應用較少,即使有的話也是一些規模較小的應用,可以參考單 HAP 的場景。
🚀 面試總結:模塊化設計決策樹
📊 決策流程圖
應用模塊化設計
├── 是否需要獨立運行和安裝?
│ ├── 是 → Feature HAP
│ └── 否 → 繼續判斷
├── 是否需要按需加載?
│ ├── 是 → HSP
│ └── 否 → 繼續判斷
├── 是否需要跨應用共享?
│ ├── 是 → HAR (通過 OHPM 倉)
│ └── 否 → HAR (應用內使用)
└── 性能 vs App Size 權衡├── 性能優先 → HAR└── App Size 優先 → HSP 模塊殼
🎯 面試記憶口訣
“獨立運行選 HAP,按需加載用 HSP,跨應用共享靠 HAR”
- HAP:獨立 Ability,獨立安裝
- HSP:動態共享,按需加載
- HAR:靜態共享,編譯打包
💪 面試優勢回答模板
面試官:如何選擇合適的模塊化方案?
完美回答:
應用開發者需根據技術架構選擇適合的工程模塊化模型。工程模塊化模型需根據業務和技術架構演進而演進。根據訴求在 HAP、HAR 和 HSP 中選擇使用。
具體選擇標準:
- 獨立運行和安裝的模塊:只能選擇 HAP 包,并將其作為 Feature 類型的 HAP 存在于 App 中
- 按需加載模塊:對于不具備獨立特性部分,用戶使用頻率較少的模塊,將其做成 HSP 按需加載模塊存在于 App 中
- 共享模塊:對于需要共享的模塊,只能采用 HAR 包,將其通過 OHPM 倉共享給其他工程使用
- 性能優化:HAR 是靜態共享庫,在多 HAP 或者按需加載場景下,在編譯后可能會在物理上存在多份,所以需要合理采用公共 HSP 模塊殼,使 App Size 最小化