鸿蒙应用开发踩坑记录

使用HarmonyOS4+ArkUI+Stage模型进行开发的翻译软件,目前只是半成品,代码写的很挫。记录一下开发过程中踩过的坑。
项目地址:
码云
https://gitee.com/huangyuan/HarmonyTranslator
github
https://github.com/huangyuanlove/HarmonyTranslator
码云项目是从github导入的,偶尔会忘记同步

冻屏、黑屏、假死

运行环境是MetaPadPro 2019 鸿蒙4.0.0,使用api9+stage模型开发,运行在模拟器上正常,但是运行在该设备上出现冻屏现象,页面轮播图无法轮播,滑动组件无法发滑动,就像卡在了这一帧上一样。点击输入框键盘能弹出,但页面是黑的。可以通过锁屏、解锁或者音量键刷新页面。

感觉上就是屏幕不会主动刷新,需要按物理键让屏幕刷新一次似的。

询问过朋友后发现,这个现象只会出现在麒麟系列芯片的手机或平板上,看到论坛也有人咨询相同的问题。向官方提工单后官方回复是已知问题,将会在HarmonyOS next系统中修复

如果只是自己写着玩,可以安装 scrcpy 将屏幕内容同步到电脑上,在电脑上操作是没有问题的。

如果是公司用,建议咨询鸿蒙运营,成为合作伙伴,直接上HarmonyOS Next进行开发。或者降低api版本。

项目中有些设置需要持久化存储,于是选择了PersistentStorage和@StorageLink方式进行存储,大致如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export class User {
constructor(name: string, age: number) {
this.name = name
this.age = age
}
name: string
age: number
}

PersistentStorage.PersistProp<User>('user', new User('xuan',18))
@Entry
@Component
struct Tmp {
@StorageLink('user') user: User = new User('xuan', 18)
build() {
Text(`${this.user.name} : ${this.user.age}`)
}
}

当我第一运行的时候,页面显示正常,Text显示的内容是xuan : 18

但是当我重新打开应用(不是重新编译,就是简单的在设备上关掉应用然后点击桌面图标打开应用)的时候,Text显示内容是 undefined : undefined

打上断点发现重新打开应用的时候 user 是一个字符串类型,值为 {‘name’:’xuan’,’age’:18},但字符串对象没有name和age属性,所以显示了 undefined.

看到文档中有写 https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/arkts-state-management-0000001504151156-V3#ZH-CN_TOPIC_0000001523808562__persistprop

AppStorage的属性向PersistentStorage中持久化的允许的类型是:

number,string,boolean,enum基础类型。

Object中可序列化的属性。

不允许undefined和null。

但同样的,在指南中同样有PersistentStorage描述 https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/arkts-persiststorage-0000001474017166-V3#section610120319595

PersistentStorage允许的类型和值有:

number, string, boolean, enum 等简单类型。

可以被JSON.stringify()和JSON.parse()重构的对象。例如Date, Map, Set等内置类型则不支持,以及对象的属性方法不支持持久化。

看到论坛有同样的求助,有开发者回复说他是将对象转成字符串保存的,使用的时候再parse一下。

剪贴板 pasteboard.getSystemPasteboard()

在使用剪贴板时需要先创建剪贴板数据,
创建方法如下

1
2
createData(mimeType: string, value: ValueType): PasteData  
createRecord(mimeType: string, value: ValueType):PasteDataRecord

第一个参数含义为:自定义数据的MIME类型。 文档中 鸿蒙开发api参考
中写的示例

1
2
3
import pasteboard from '@ohos.pasteboard';
let dataXml = 'Hello World';
let pasteDataRecord = pasteboard.createRecord('app/xml', dataXml);

实际中发现时不能使用这自定义的app/xml值,会崩溃,只能使用pasteboard中预定义的MIME类型

对象属性从有值变为空,应用会崩溃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@Entry
@Component
struct PlayGround {
@State people:People = new People()
private log(log:string):boolean{
console.error(`---------${log}---------`)
return true
}

build(){
Column() {
if(this.people){
Text(`姓名: ${this.people.name} 年龄:${this.people.age}`)
if(this.people.address){
if(this.log('address 有值')){
Text( `地址: ${this.people.address.name} 邮编:${this.people.address.zipCode}`)
}
else{
Text('address 为空 内部')
}
}else{
if(this.log('address 为空 最外层')){
Text('address 为空 最外层')
}
}
}
Button('网络请求返回一个有地址的对象').onClick(()=>{
let tmpPeople = new People()
let tmpAddress = new Address()
tmpAddress.name = '测试地址'
tmpAddress.zipCode = -1000
tmpPeople.address = tmpAddress

tmpPeople.age = 10
tmpPeople.name = '有地址'
this.people = tmpPeople
})

Button('网络请求返回一个没有地址的对象').onClick(()=>{
let tmpPeople = new People()
tmpPeople.age = 10
tmpPeople.name = '没有地址'
this.people = tmpPeople
})
}.margin({top:48})
}
}
class Address{
zipCode:number
name:string
}
class People{
name:string
age:number
address :Address
}

很简单的页面,展示对象属性,
刚开始运行,一切正常。点击返回有地址的对象,页面正常刷新并且展示。然后点击返回没有地址的对象,这时候会崩溃。
日志指向了 Text( 地址: ${this.people.address.name} 邮编:${this.people.address.zipCode})
说是不能从undefined对象中读取name属性 具体可以看这里:开发这论坛
规避方案:我有一个朋友,尝试出了使用 ?.来规避的方法。 取对象属性除了要用if判断来控制渲染之外,需要用 ?.来取值,防崩溃,将上面的代码修改为
Text( 地址: ${this.people.address?.name} 邮编:${this.people.address?.zipCode})
应用不会崩溃,这个对象也不会渲染在页面上

但根据文档描述,既然if条件不成立,下面的Text组件就不应该被渲染,也不应该读取address的name属性。同样提工单,回复说是双框架问题,将在HarmonyOS Next版本解决

需要注意的是,文档上写的被状态管理装饰器修饰的变量,基本上都不支持any、undefined、null值,但实际写代码的过程中是没有校验的,目前来看即使是这些类型或者值,也是没什么大问题的,但还是建议大家按文档写,有问题咨询相关技术人员或者论坛、提工单。


以上


鸿蒙应用开发踩坑记录
https://blog.huangyuanlove.com/2023/11/29/鸿蒙应用开发踩坑记录/
作者
HuangYuan_xuan
发布于
2023年11月29日
许可协议
BY HUANG兄