跟着小白一起学鸿蒙--JS应用控制LED(十)

系统 OpenHarmony
Ace(foundation/arkui/ace_engine_lite)是OpenHarmony的轻量级系统所使用的UI框架子系统,为开发者提供JS-UI开发框架。包括.html,.css,.js。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

在《#跟着小白一起学鸿蒙# [九] 写个简单的LED驱动》我们熟悉了如何在开源鸿蒙开发驱动应用,并通过hdc工具拷贝至开发板运行。在《#跟着小白一起学鸿蒙#[六]第一个hap应用》的文章里我们学会如何用IDE工具编写hap应用并他通过IDE工具安装至开发板运行。我们学会了hap程序的开发,但是hap程序是运行在标准系统的应用,对于轻量和小型系统我们应该如何进行开发呢?接下来我们需要学习下如何开发JS应用。

轻量、小型系统JS应用

Ace(foundation/arkui/ace_engine_lite)是OpenHarmony的轻量级系统所使用的UI框架子系统,为开发者提供JS-UI开发框架。包括.html,.css,.js。开发者可以通过DevEco工具进行开发。其中JS的引擎采用三方库里的JerryScript(jerryscript是IoT设备上的轻量级JS引擎,支持ECMAScript 5.1标准,适配低内存硬件,最小运行在64KB RAM和小于200KB的flash,提供C API)。关于jerryscript的详细介绍可以看如下参考链接(https://github.com/jerryscript-project/jerryscript )。

#冲刺创作新星# #跟着小白一起学鸿蒙# [十] JS应用控制LED-开源基础软件社区

详细的内容介绍在一下链接内可以看到官方的说明:

参考链接:https://gitee.com/openharmony/arkui_ace_engine_lite。

此样例参考小熊派设计,使用小熊派HM_Micro开发板进行验证。

JS-UI开发流程

graph LR
--> 配置工程 --> 增加LED程序 --> 添加JSAPI接口

创建工程配置工程增加LED程序添加JSAPI接口编译运行。

建立[Lite]Empty Ability。

#冲刺创作新星# #跟着小白一起学鸿蒙# [十] JS应用控制LED-开源基础软件社区

配置工程。

#冲刺创作新星# #跟着小白一起学鸿蒙# [十] JS应用控制LED-开源基础软件社区

工程结构说明。

#冲刺创作新星# #跟着小白一起学鸿蒙# [十] JS应用控制LED-开源基础软件社区

工程目录主要在entry里,有以下内容:

  • .preview: 界面预览目录。
  • build: 工程编译目录。
  • src:包括i18n(国际化翻译路径),pages(界面目录,index.css, index.hml, index.js)。

工程预览。

#冲刺创作新星# #跟着小白一起学鸿蒙# [十] JS应用控制LED-开源基础软件社区

添加按键功能控制LED灯。

  • 修改index.hml
<div class="container">
<text class="title">
{{ $t('strings.hello') }} {{ title }}
</text>

<div class="rowcontainer">
<text class="content" if="{{statu == '0'}}">[状态:{{ $t('strings.ledoff') }}]</text>
<text class="content" if="{{statu == '1'}}">[状态:{{ $t('strings.ledon') }}]</text>
<text class="content" onclick="ledon">
{{ $t('strings.ledon') }}
</text>
<text class="content" onclick="ledoff">
{{ $t('strings.ledoff') }}
</text>
<text class="content" onclick="ledtoggle">
{{ $t('strings.ledtoggle') }}
</text>
</div>
<text class="content" onclick="exit">
{{ $t('strings.exit') }}
</text>
</div>
  • 修改index.css
.container {
width: 100%;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
}
.title {
width: 200px;
font-size: 30px;
text-align: center;
}
.content{
width: 200px;
font-size: 30px;
text-align: center;
}
.rowcontainer {
width: 100%;
height: 50%;
flex-direction: row;
justify-content: center;
align-items: center;
}
  • 修改index.js
var led = {open:1,close:0,change:2}
import app from '@system.app';
export default {
data: {
title: "",
statu:'0'
},
onInit() {
this.title = this.$t('strings.world');
},
ledon(e) {
let that = this
console.info("ledon")
app.ledcontrol({
code:led.open,
success(res){
that.statu = res.led_status
},
fail(res,code){
console.error("ledon error")
},
complete(){
console.info("ledon complete")
}
})
},
ledoff(e) {
let that = this
console.info("ledoff")
app.ledcontrol({
code:led.close,
success(res){
that.statu = res.led_status
},
fail(res,code){
console.error("ledoff error")
},
complete(){
console.info("ledoff complete")
}
})
},
ledtoggle(e) {
let that = this
console.info("ledtoggle")
app.ledcontrol({
code:led.change,
success(res){
that.statu = res.led_status
},
fail(res,code){
console.error("ledtoggle failed")
},
complete(){
console.info("ledtoggle complete")
}
})
},
exit(e) {
app.terminate()
},
}
  • 预览

#冲刺创作新星# #跟着小白一起学鸿蒙# [十] JS应用控制LED-开源基础软件社区

  • 将代码编译成hap包:点击编辑器最左下角的OhosBuild Varilants,打开编译模式选择视图,编译模式分debug和release,选择release模式;
  • 点击编辑器上方菜单栏的Build->Build Hap(s)/App(s)->Build Hap(s),系统就会开始自动编译代码成hap包,等到下方Build Output无编译错误,就表示代码编译完成了。

增加JS的API接口。

  • 在app_module.h里增加接口

JSI::SetModuleAPI(exports, "ledcontrol", AppModule::ToggleLed);

  • 在app_module.cpp里增加接口实现
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"
#define LED_WRITE_READ 1
#define LED_SERVICE "hdf_led"
......
static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
{
uint32_t value;
HdfSbufReadUint32(data, &value);
HILOG_ERROR(HILOG_MODULE_ACE,"%s: dev event received: %u %u\n", (char *)priv, id, value);

return HDF_SUCCESS;
}
static int GpioWriteRead(struct HdfIoService *serv, int32_t eventData, int32_t *val)
{
int ret = HDF_FAILURE;
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();

if (data == NULL || reply == NULL) {
HILOG_ERROR(HILOG_MODULE_ACE,"fail to obtain sbuf data\n");
return ret;
}
if (!HdfSbufWriteUint8(data, (uint8_t)eventData))
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to write sbuf\n");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
if (ret != HDF_SUCCESS)
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to send service call\n");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
if (!HdfSbufReadInt32(reply, val))
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service call reply\n");
ret = HDF_ERR_INVALID_OBJECT;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
HILOG_ERROR(HILOG_MODULE_ACE,"Get reply is: %d\n", val);

HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
JSIValue AppModule::ToggleLed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
HILOG_ERROR(HILOG_MODULE_ACE, "led button pressed.");
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE);
if (serv == NULL)
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service2 %s\n", LED_SERVICE);
return JSI::CreateUndefined();
}
if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {
return JSI::CreateUndefined();
}
JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS);
JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);

int32_t num = (int32_t)JSI::GetNumberProperty(args[0], "code");

int32_t replyData = 0;

if (GpioWriteRead(serv, num, &replyData))
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to send event\n");
JSI::CallFunction(fail, thisVal, nullptr, 0);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete);
return JSI::CreateUndefined();
}
JSIValue result = JSI::CreateObject();
JSI::SetNumberProperty(result, "led_status", replyData);
JSIValue argv[ARGC_ONE] = {result};
JSI::CallFunction(success, thisVal, argv, ARGC_ONE);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete, result);

HdfIoServiceRecycle(serv);

return JSI::CreateUndefined();
}
  • 在foundation\ace\ace_engine_lite\ace_lite.gni中添加HDF头文件路径
ace_lite_include_dirs += [    
......
"//drivers/framework/ability/sbuf/include",
"//drivers/framework/include/core",
"//drivers/framework/include/utils",
"//drivers/adapter/uhdf/posix/include",
]
  • 添加编译依赖
修改foundation\ace\ace_engine_lite\frameworks\BUILD.gn,在public_deps中添加以下代码
"//drivers/adapter/uhdf/manager:hdf_core",
修改foundation\ace\ace_engine_lite\test\ace_test_config.gni,在extra_deps中添加以下代码
"//drivers/adapter/uhdf/manager:hdf_core",

总结

  1. 基于JS扩展的类Web开发范式的方舟开发框架,采用经典的HML、CSS、JavaScript三段式开发方式。使用HML标签文件进行布局搭建,使用CSS文件进行样式描述,使用JavaScript文件进行逻辑处理。UI组件与数据之间通过单向数据绑定的方式建立关联,当数据发生变化时,UI界面自动触发更新。此种开发方式,更接近Web前端开发者的使用习惯,快速将已有的Web应用改造成方舟开发框架应用。主要适用于界面较为简单的中小型应用开发;
  2. 通过appmodule调用framework层接口,然后通过framework接口调用Hdf接口。

这样我们就有了自己的driver和配置,后面的章节我们会讲如何在hap应用里调用驱动接口。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区
相关推荐

2022-10-10 14:47:04

蓝牙应用鸿蒙

2022-10-17 14:29:24

鸿蒙应用开发

2022-12-02 14:20:09

Tetris鸿蒙

2022-11-29 16:35:02

Tetris鸿蒙

2023-03-30 09:32:27

2022-11-14 17:01:34

游戏开发画布功能

2023-02-27 16:30:32

鸿蒙开源协议分析

2022-08-19 19:02:20

开源鸿蒙操作系统

2023-03-30 09:19:54

SELinux安全子系统

2023-04-04 09:24:11

鸿蒙HiDumper

2022-12-09 15:34:38

2023-01-03 15:09:10

鸿蒙常用工具

2022-10-09 15:05:50

NAPI框架鸿蒙

2023-03-15 16:19:03

BinderIPC工具

2022-11-24 14:34:41

Hap程序鸿蒙

2022-12-06 15:39:16

鸿蒙主干代码

2022-09-30 14:08:26

Hap应用鸿蒙

2022-10-31 15:35:02

Wi-Fi蓝牙子系统

2022-11-08 15:43:45

开源鸿蒙蓝牙协议栈

2022-11-03 15:47:04

HTTP通信协议
点赞
收藏

51CTO技术栈公众号