鸿蒙 6.0 应用开发面试:应用程序包问题
鸿蒙 6.0 应用开发涉及应用程序包的多种核心问题。内容涵盖 HAR 与 HSP 包的区别、打包机制对体积的影响、代码安全措施、SO 库引用方法、应用卸载判断、Entry 与 Feature 模块区别、HSP 编译产物、HAR 转 HSP 及切换方法、跨模块页面跳转方案(命名路由、Navigation 组件、自定义框架)以及 HSP 共享流程。重点解析了静态共享与动态共享的加载时机差异,以及如何通过配置实现模块间的解耦与按需加载。

鸿蒙 6.0 应用开发涉及应用程序包的多种核心问题。内容涵盖 HAR 与 HSP 包的区别、打包机制对体积的影响、代码安全措施、SO 库引用方法、应用卸载判断、Entry 与 Feature 模块区别、HSP 编译产物、HAR 转 HSP 及切换方法、跨模块页面跳转方案(命名路由、Navigation 组件、自定义框架)以及 HSP 共享流程。重点解析了静态共享与动态共享的加载时机差异,以及如何通过配置实现模块间的解耦与按需加载。

HAR(静态共享包)编译时打包:代码和资源在构建阶段被完整复制到每个依赖它的 HAP 中。启动即加载:随应用启动直接载入内存,调用时无额外开销。适用场景:少量模块引用、对加载速度敏感的场景(如基础工具库)。
HSP(动态共享包)运行时共享:仅存储一份实例,多个 HAP 在运行时动态加载同一份 HSP。按需加载:首次调用需查找、初始化,有性能损耗但避免重复拷贝。适用场景:被大量 HAP 引用的公共模块(如 UI 组件库),可显著减少包体积。
HSP 编译生成的 HAR 包仅包含配置文件和接口定义,不包含代码逻辑。该 HAR 包仅用于开发阶段,不会影响 App 包的大小。
target_link_libraries(entry PUBLIC libxxx)libxxx.so 库文件放入 HAR 或 HSP 的 libs/arm64-v8a 目录。设备类型不同时,需添加对应子目录。新版的 arm64 为 libs/arm64-v8a,老版的 arm64 为 libs/armeabi-v7a,x86 模拟器为 libs/x86_64。HSP 包编译后会生成.hsp 文件和.har 文件。.hsp 文件用于安装,.har 文件仅暴露接口,不包含具体实现。HSP 包中导出的方法头文件位于.har 文件中,实现在.hsp 文件中。
HAR 转为 HSP 主要是通过修改配置文件实现。具体步骤如下:
编译过程中遇到其他错误时,根据提示找到对应位置并进行修改。
在业务体系庞大或复杂的情况下,会将业务拆分成多个子业务模块,每个子业务模块为一个 HAR/HSP。在该场景下,存在从主业务入口跳转到不同子页面模块,或从一个子业务模块 A 页面跳转到另一个子业务模块 B 页面的需求。例如,从应用首页跳转到登录子业务模块页面。针对该场景,有以下三种解决方案:
@Component 装饰器定义了一个名为 LoginPage 的结构体组件。@Consume('pathStack') 注解,组件从其父组件中获取 NavPathStack 实例,用于页面导航。@State 声明了一个字符串类型的状态变量 message,初始值为 'Login Page'。build 方法中,使用 NavDestination 构建导航目标,内部包含一个 Column 布局。Column 中,使用 Text 组件显示 message 变量的值,并设置字体大小为 50,字体加粗。Column 的宽度和高度为 100%。.onBackPressed 方法注册返回按钮的事件处理函数,当返回按钮被按下时,调用 pathStack.pop() 方法返回到上一个页面,并返回 true 表示事件已被处理。LoginPage 组件,这是从 @ohos/login 模块中导入的。NavigationPage 组件:使用 @Entry 和 @Component 装饰器定义了一个名为 NavigationPage 的组件。pathStack:使用 @Provide 装饰器定义了一个名为 pathStack 的 NavPathStack 实例,用于管理页面导航路径。pageMap 方法:使用 @Builder 装饰器定义了一个名为 pageMap 的方法,该方法根据传入的 name 参数决定返回哪个组件。如果 name 是 'loginPage',则返回 LoginPage 组件。build 方法中,使用 Navigation 组件和 Button 组件构建了一个 UI。Navigation 组件使用 pathStack 来管理导航路径。Button 组件显示一个按钮,点击后会创建一个 NavPathInfo 对象,并使用 pathStack.pushDestination 方法导航到 loginPage。.navDestination(this.pageMap) 设置导航的目标为 pageMap 方法返回的组件。// Import a custom component of the Login module
import { LoginPage } from '@ohos/login';
@Entry
@Component
struct NavigationPage {
@Provide('pathStack') pathStack: NavPathStack = new NavPathStack();
@Builder pageMap(name: string) {
if (name === 'loginPage') {
LoginPage()
}
}
build() {
Navigation(this.pathStack) {
Button('jump to login page').onClick(() => {
// The second parameter of NavPathInfo is a custom parameter that can be used for message transfer
let pathInfo: NavPathInfo = new NavPathInfo('loginPage', new Object());
this.pathStack.pushDestination(pathInfo, true);
})
}.navDestination(this.pageMap)
}
}
代码逻辑走读:
在入口模块的 oh-package.json5 文件中添加对 Login 模块的依赖项。
{
"...",
"dependencies": {
"@ohos/login": "file:../LoginModule"
}
}
在 Login 模块的入口文件 Index.ets 中导出自定义组件。
export { LoginPage } from './src/main/ets/pages/loginPage';
在 Login 模块中开发自定义组件 LoginPage 作为路由跳转目的地,并对外导出。
@Component
export struct LoginPage {
@Consume('pathStack') pathStack: NavPathStack;
@State message: string = 'Login Page';
build() {
NavDestination() {
Column() {
Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)
}.width('100%').height('100%')
}.onBackPressed(() => {
this.pathStack.pop();
return true;
})
}
}
入口模块导入 Login 模块的自定义组件,并添加到 Navigation 组件的路由表中。
如需在应用内共享 HSP,请将 HSP 共享包上传至私仓。动态共享包 HSP 不能直接发布在私仓内,需要先转换为.tgz 包。请按以下操作编译生成*.tgz 包。
ohpm install 命令将依赖安装到工程的 oh-package.json5 文件的 dependencies 字段中,即可查看对外共享的 HSP 方法。
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online