鸿蒙中ArkTS常见问题(一)

80 阅读4分钟

问题1:将rawfile中json格式的字符串转换成对应的object对象后,调用实例方法后程序崩溃

问题现象

直接报错:"jscrash happened in xxxxxxxxx",crash日志中错误信息:"Error message: Unexpected Object in JSON"。

解决措施

通过json解析字符串得到的对象的原型是object,其原型链中不存在自有的实例方法,故无法调用。

如需调用该方法,则有以下两种方式:

  1. 在解析后的对象上添加对应的原型,也就是转换创建对应实例对象:

JSON.parse方法会把 function 处理成字符串,直接调用的话会因该 function 不可调用从而 crash;为了能够继续使用,一般使用 eval 函数把字符串转成 function,但是 ArkTS 中会限制使用 eval 函数,所以该方法不可行,解决方案就是使用 class-transformer 的 plainToClass 方法;

在oh-package.json5中添加第三方插件class-transformer的依赖;

import { plainToClass } from"class-transformer";

通过调用第三方插件class-transformer的plainToClass方法转换成类对象,

plainToClass(myInfo,infoTmp);

  1. 将该实例方法改为静态方法,通过类名去调用。

问题2:如何使用正则表达式

首先定义一个正则表达式:

const reg = new RegExp('ba');

使用正则表达式:

const res = reg.test('bar'); 
console.info('result', res);

问题3:import依赖树较大如何优化

可以动态加载,解决依赖过大的问题。ArkCompiler支持动态import方法,支持运行时阶段动态加载模块。

  1. 通过import()接收一个模块路径作为参数,返回一个Promise对象。
  2. 当Promise对象被resolve时,使用then()方法获取模块的默认导出。

可参考如下示例代码:

try { 
  // 加载所需模块 
  import('./Index').then(module => { 
    // 在需要时使用所需模块的代码 
    // ... 
  }) 
} catch (error) { 
  // ... 
}

问题4:如何将Resource资源对象转成string类型

  1. 通过getSystemResourceManager接口获取ResourceManager对象。
  2. 再使用getStringValue接口获取指定资源ID对应的字符串。

可以参考以下示例代码:

import { resourceManager } from '@kit.LocalizationKit'; 
import { BusinessError } from '@kit.BasicServicesKit'; 

try { 
  let systemResourceManager = resourceManager.getSystemResourceManager(); 
  systemResourceManager.getStringValue($r('sys.string.ohos_lab_vibrate').id).then((value: string) => { 
    console.info("sys.string.ohos_lab_vibrate value is " + value); 
  }).catch((error: BusinessError) => { 
    console.error(`systemResourceManager getStringValue promise error is ${JSON.stringify(error)}`); 
  }); 
} catch (error) { 
  let code = (error as BusinessError).code; 
  let message = (error as BusinessError).message; 
  console.error(`systemResourceManager getStringValue failed, error code: ${code}, message: ${message}.`); 
}

问题5:如何实现ArkUI组件字符串变量拼接

问题现象

例如:Text()组件的字符串变量拼接功能,如何实现?

Text($r('app.string.EntryAbility_desc', 'Hello'))

解决措施

可以通过资源文件结合%d、%s的方式进行实现。

示例如下所示:

  1. 修改"src/main/resources/zh_CN/element/string.json"文件,对其中的一个需要变量拼接内容增加%d拼接。
{ 
  "string": [ 
    { 
      "name": "module_desc", 
      "value": "模块描述%d" 
    }, 
    { 
      "name": "EntryAbility_desc", 
      "value": "description" 
    }, 
    { 
      "name": "EntryAbility_label", 
      "value": "label" 
    } 
  ] 
}

修改"src/main/resources/en_US/element/string.json"文件,对其中的一个需要变量拼接内容增加%d拼接。

{ 
  "string": [ 
    { 
      "name": "module_desc", 
      "value": "module description%d" 
    }, 
    { 
      "name": "EntryAbility_desc", 
      "value": "description%d" 
    }, 
    { 
      "name": "EntryAbility_label", 
      "value": "label" 
    } 
  ] 
}
  1. 在页面组件中使用$r(xx)加上拼接变量进行使用。
@Entry 
@Component 
struct Page1 { 
  @State num1: number = 100; 

  build() { 
    Row() { 
      Column() { 
        Text($r('app.string.module_desc', this.num1)) 
          .fontSize(50) 
          .fontWeight(FontWeight.Bold) 
      } 
      .width('100%') 
    } 
    .height('100%') 
  } 
}
  1. 切换中英文语言时,会自动跟随语言的切换带入对应的变量信息。

问题6:如何实现应用的屏幕自动旋转

  1. 在module.json5添加属性"orientation": "auto_rotation"。

如下所示:

"abilities": [ 
  { 
    "name": "EntryAbility", 
    "srcEntry": "./ets/entryability/EntryAbility.ets", 
    "description": "$string:EntryAbility_desc", 
    "icon": "$media:icon", 
    "label": "$string:EntryAbility_label", 
    "startWindowIcon": "$media:startIcon", 
    "startWindowBackground": "$color:start_window_background", 
    "exported": true, 
    "skills": [ 
      { 
        "entities": [ 
          "entity.system.home" 
        ], 
        "actions": [ 
          "action.system.home" 
        ] 
      } 
    ], 
    "orientation": "auto_rotation", // 随传感器旋转 
  } 
]
  1. 再打开手机自动旋转按钮即可。

问题7:如何生成随机的uuid

util工具函数中通过util.generateRandomUUID接口提供了生成uuid的相应功能

问题8:ArkTS中有类似java中的System.arraycopy数组复制的方法吗?

可以通过buffer.concat()方法,将数组中的内容复制指定字节长度到新的Buffer对象中并返回。

问题9:如何实现字符串编解码

TextEncoder用于将字符串编码为字节数组,支持多种编码格式,包括utf-8、utf-16le/be等。

TextDecoder用于将字节数组解码为字符串,可以处理多种编码格式,包括utf-8、utf-16le/be、iso-8859和windows-1251等不同的编码格式。

示例代码

import { util } from '@kit.ArkTS';
// 创建编码器
let textEncoder:util.TextEncoder = new util.TextEncoder('gbk');
let buffer:ArrayBuffer = new ArrayBuffer(20);
let encodeResult:Uint8Array = new Uint8Array(buffer);


// 编码
encodeResult = textEncoder.encodeInto('hello');
console.info('Encode result: ', encodeResult);


// 创建解码器
let textDecoder = util.TextDecoder.create('gbk');


// 解码
let decodeResult = textDecoder.decodeToString(encodeResult); 
console.info('Decode result: ', decodeResult);

问题10:synchronized在java中可以修饰方法,从而简单地实现函数的同步调用。在系统ets开发中,如何简单实现该功能。

支持AsyncLock形式的同步机制,将需要同步的代码块放到异步代码块中。

问题11:ArkTS类的方法是否支持重载。

当前ArkTS支持TS中的重载,即多个重载签名+实现签名+函数体的形式。函数签名只用在编译期进行类型检查,不保留到运行时。

ArkTS不支持多个函数体实现的重载。示例如下:

// 声明 
function test(param: User): number; 
function test(param: number, flag: boolean): number; 
// 实现 
function test(param: User | number, flag?: boolean) { 
  if (typeof param === 'number') { 
    return param + (flag ? 1 : 0) 
  } else { 
    return param.age 
  } 
}