鸿蒙面试浪潮来袭,你是否也想着利用这次机会去实现,跳槽涨薪的梦呢?
如果关注了华为鸿蒙的人应该知道:鸿蒙开发岗位需求飙升6倍! 可想而知该岗位前景多么广阔,为此就为大家整理些(鸿蒙HarmonyOS)开发岗位面试题。
面试题目
- 页面和组件的生命周期,及其流程
- @Entry 装饰的页面和 Navigation 组件里的页面,有什么区别
@Entry 装饰的页面
1.定义:是一个基本的页面,每一个页面都需要在 main_page.json 中声明
2.路由:这种页面是路由的起点,通常用于展示应用的入口
3.生命周期:具有通用的生命周期方法,如 @Entry 修饰的页面中的通用方法
Navigation 组件
1.定义:是一个导航容器,挂载在单个页面下
2.路由:支持跨模块的动态路由,通过自定义路由表或系统路由表实现页面的跳转
3.页面结构:由标题栏、内容区和工具栏组成,支持页面的路由能力和多种显示模式
4.显示模式:可以设置为单页显示或分栏显示模式,适应不同设备尺寸
- 常用的状态装饰器有哪些
- 常用的动画有哪些
一、组件的属性动画
二、页面间的转场动画
三、lolita 库加载动画资源文件
- ArkTs 和 Ts 有什么区别
- 动态 import 加载模块,以及反射
// Calc.ets
export class Calc {
public constructor() {}
public static staticAdd(a: number, b: number): number {
return a + b;
}
public instanceAdd(a: number, b: number): number {
return a + b;
}
}
export function addHarLibrary(a: number, b: number): number {
return a + b;
}
// index.ets
let harLibrary = 'harlibrary'
// 动态import变量是新增特性,入参换成字符串'harlibrary'是现有特性。也可使用await import方式
import(harLibrary).then((ns: ESObject) => {
// 反射调用静态成员函数staticAdd()
ns.Calc.staticAdd(7, 8);
// 实例化类Calc
let calc: ESObject = new ns.Calc();
// 调用实例成员函数instanceAdd()
calc.instanceAdd(8, 9);
// 调用全局方法addHarLibrary()
ns.addHarLibrary(6, 7);
})
- 如何做沉浸式状态栏
- 理解沉浸式状态栏
沉浸式状态栏是指应用程序的内容充满整个屏幕,包括状态栏区域,从而提供更流畅、更沉浸的用户体验。在鸿蒙系统中,可以通过设置全屏布局和调整状态栏颜色等方式来实现沉浸式效果。- 实现沉浸式状态栏的具体方法
方法一:使用setWindowLayoutFullScreen方法
这是鸿蒙系统提供的一个直接设置全屏的方法,通过调用此方法可以实现沉浸式状态栏效果。具体步骤如下:
在onWindowStageCreate方法中获取主窗口对象。
调用setWindowLayoutFullScreen(true)方法将窗口布局设置为全屏
代码示例:
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.getMainWindow().then(window => {
window.setWindowLayoutFullScreen(true);
});
// 加载页面内容
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
console.error('Failed to load the content', err);
return;
}
console.info('Succeeded in loading the content', data);
});
}
方法二:设置背景色统一
如果只需要实现状态栏与导航栏、主内容区的颜色统一,可以通过设置整体窗口的背景色来实现视觉上的沉浸式效果。这种方法不需要将窗口设置为全屏,但可以通过颜色的统一来减少突兀感
onWindowStageCreate(windowStage: window.WindowStage): void {
// 加载页面内容
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
console.error('Failed to load the content', err);
return;
}
// 设置背景色实现沉浸式
windowStage.getMainWindowSync().setWindowBackgroundColor('#9F6BF5');
});
}
- 如何实现垂直的三栏布局
- @Entry 装饰的页面,A 页面跳到 B 页面后再跳回 A 页面,如何获取 B 页面的返回值
router.back({
url: 'pages/Home',
params: {
info: '来自Home页'
}
})
// 这些参数可以在目标页面中
// 通过调用 router.getParams() 方法进行获取
onPageShow() {
const params = router.getParams() as Record<string, string>
console.log(params)
}
- 如何实现给父组件传递子组件
使用 @BuilderParam
以下示例代码是我个人开发中该组件的简化版
@Component
export struct Visible {
@Prop isShow: boolean = true
@BuilderParam children: () => void = this.EmptyBuilder
@Builder
EmptyBuilder() {
}
build() {
Column() {
this.children()
}
.visibility(this.isShow ? Visibility.Visible : Visibility.Hidden)
}
}
// 使用
Visible({ isShow: true }) {
Tech()
}
- 使用router.back() 方法返回到原来的页面,会触发原页面的 aboutToAppear() 生命周期回调吗,会触发哪个生命周期?
不会触发 aboutToAppear,但是会触发 onPageShow()
12.UIAbility 和 WindowStage 的生命周期,及其流程
12. Model 分为几种类型,分别是什么
13. Model 分为几种类型,分别是什么
-
Hap、Har、Hsp 分别是什么,它的特点及其应用场景
-
简单说下开发阶段、编译阶段、发布阶段的包结构
-
什么是应用模型
-
简单解释下 Stage 模型
-
build() 函数内的语法需要遵守什么限制
19.web 和原生组件通信
import { webview } from '@kit.ArkWeb'
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController()
build() {
Column() {
// 三种加载网页的方式
Web({ src: $rawfile("index.html"), controller: this.controller })
Web({ src: "resource://rawfile/index.html", controller: this.controller })
Web({ src: 'www.example.com', controller: this.controller })
.zoomAccess(false)
.aspectRatio(1)
.javaScriptAccess(true)
.onPageEnd(async e => {
// 调用网页内函数并获取返回值
const res = await this.controller.runJavaScript('test()')
})
// 页面上调用 confirm() 函数时触发,以此来实现页面向原生通信
.onConfirm(event => {
})
}
}
}
// module.json5 访问网络前需要申请网络权限
"module": {
"requestPermissions": [
{"name": "ohos.permission.INTERNET"}
]
}
20.持久化存储
preference: preferences.Preferences
this.preference = preferences.getPreferences(getContext(this), 'my-preference')
// 读取,异步的方法,也有 getSync 这样同步的方法
const res = await this.preference.get(key, defaultValue)
// 写入
this.preference.put('accountInfo', response)
// 写到文件
this.preference.flush()
// 清空
this.preference.clear()
21.Worker 和 TaskPool 的区别