鸿蒙应用开发面试题
- 目前鸿蒙的面试题相对比都比较简单。部分面试题内容答案来源于网络,不保证百分之百正确
- 鸿蒙面试有很大概率会问一些前端和Android的相关问题
1. 页面和自定义组件生命周期区别
在开始之前,我们先明确自定义组件和页面的关系:
- 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
- 页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。
页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:
- onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
- onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
- onBackPress:当用户点击返回按钮时触发。
组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:
- aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
- onDidBuild:组件build()函数执行完成之后回调该接口,不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。
- aboutToDisappear:aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。
生命周期流程如下图所示,下图展示的是被@Entry装饰的组件(页面)生命周期。
2. 装饰器用过哪些分别是什么
- @Component装饰器:装饰的UI单元
- @Builder装饰器:自定义构建函数
- @BuilderParam装饰器:引用@Builder函数
- @Styles装饰器:定义组件重用样式
- @Extend装饰器:定义扩展组件样式
- @AnimatableExtend装饰器:定义可动画属性
状态管理
- V1稳定版
- @State装饰器:组件内状态
- @Prop装饰器:父子单向同步
- @Link装饰器:父子双向同步
- @Provide装饰器和@Consume装饰器:与后代组件双向同步
- @Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化
- @Watch装饰器:状态变量更改通知
- @Track装饰器:class对象属性级更新
- V2试用版
- @ObservedV2装饰器和@Trace装饰器:类属性变化观测
- @ComponentV2装饰器:自定义组件
- @Local装饰器:组件内部状态
- @Param:组件外部输入
- @Once:初始化同步一次
- @Event装饰器:组件输出
- @Monitor装饰器:状态变量修改监听
- @Provider装饰器和@Consumer装饰器:跨组件层级双向同步
- @Computed装饰器:计算属性
3. Ability生命周期,以及如何与绑定的UI通信
这里的Ability指的就是UIAbility
1. UIAbility生命周期
UIAbility的生命周期包括Create、Foreground、Background、Destroy四个状态,如下图所示。
2. UIAbility与绑定的UI通信
基于当前的应用模型,可以通过以下几种方式来实现UIAbility组件与UI之间的数据同步。
- 使用EventHub进行数据通信:在基类Context中提供了EventHub对象,可以通过发布订阅方式来实现事件的传递。在事件传递前,订阅者需要先进行订阅,当发布者发布事件时,订阅者将接收到事件并进行相应处理。
- 使用AppStorage/LocalStorage进行数据同步:ArkUI提供了AppStorage和LocalStorage两种应用级别的状态管理方案,可用于实现应用级别和UIAbility级别的数据同步。
4. SQLite,讲讲具体作用是什么,如何使用的
关系型数据库基于SQLite组件,适用于存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需要使用关系型数据库来持久化保存数据
import { relationalStore } from "@kit.ArkData"
import User from "../model/User"
class RelationalStoreUtil{
private store:relationalStore.RdbStore | undefined = undefined
/**
* 初始化数据库
* @param context
* @param config
* @param sql
*/
loadRelationalStore(context:Context,config:relationalStore.StoreConfig,sql:string){
relationalStore.getRdbStore(context,config,(err,store) => {
if (err) {
console.log("myDB", "创建数据库对象失败")
return;
}
// 创建数据表
store.executeSql(sql)
this.store = store
console.log("myDB", "数据库创建成功")
})
}
/**
* 添加数据
* @param tableName
* @param data
* @returns
*/
async insertStore(tableName:string,data:relationalStore.ValuesBucket){
if(this.store !== undefined){
return await this.store.insert(tableName,data)
}
return
}
/**
* 查询数据
* @param tableName
* @param fields
*/
async selectStore(tableName:string,fields:Array<string>){
let user:User[] = []
let predicates = new relationalStore.RdbPredicates(tableName)
if(this.store !== undefined){
let result = await this.store.query(predicates,fields)
while (result.goToNextRow()){
const id = result.getLong(result.getColumnIndex("id"))
const name = result.getString(result.getColumnIndex("name"))
const age = result.getLong(result.getColumnIndex("age"))
user.push(new User(id,name,age))
}
// 释放数据库资源
result.close()
return user
}
return []
}
}
export default new RelationalStoreUtil()
5. 如何获取上下文信息,获取以后做了什么事情
Context是应用中对象的上下文,其提供了应用的一些基础信息,例如resourceManager(资源管理)、applicationInfo(当前应用信息)、dir(应用文件路径)、area(文件分区)等,以及应用的一些基本方法,例如createBundleContext()、getApplicationContext()等。UIAbility组件和各种ExtensionAbility派生类组件都有各自不同的Context类。分别有基类Context、ApplicationContext、AbilityStageContext、UIAbilityContext、ExtensionContext、ServiceExtensionContext等Context
1. 获取上下文信息Context
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct Page_Context {
private context = getContext(this) as common.UIAbilityContext;
}
2. 获取之后做了什么事情
- 用户首选项需要Context
preferences.getPreferencesSync(this.context, { name:"myStore" })
- 键值型数据库需要Context
const kvManagerConfig: distributedKVStore.KVManagerConfig = {
context: this.context,
bundleName: 'com.example.kvstoredemo'
}
- 关系型数据库需要Context
relationalStore.getRdbStore(this.context,config)
6. prop和link的区别
@Prop装饰器:父子单向同步 @Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。
- @Prop变量允许在本地修改,但修改后的变化不会同步回父组件。
- 当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件 (所属组件),子组件数值的变化不会同步到父组件
@Link装饰器:父子双向同步 子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。
@Link装饰的变量与其父组件中的数据源共享相同的值。