目录:
前言
JS应用开发框架原理
内置模块
实现ace模块
开发界面程序

前言
上回说到,用C++来写UI界面的开发效率不如JS+HTML来的高,但设备开发又免不了要通过内核态来操作硬件,这里我们就要先打通从JS框架到设备驱动之间的联系。本章基于HDF驱动和JS+CSS+HTML的技术上进行,相关内容可以回顾用鸿蒙开发AI应用(五)HDF 驱动补光灯和用鸿蒙开发AI应用(六)UI篇这两篇。
 

JS应用开发框架原理
在第六篇里,我们已经体验了一下使用JS开发界面的流程,这里简单分析ace的实现原理。

先看框架图,类小程序的Web应用先编译成js bundle包,通过JS Data binding来获取对象映射。其中Observer实现了一个极简的MVVC模型,用于将DOM上的对象分为4种类型(render、data、styleSheet、function),采用数据劫持机制分别挂载到观察者的原型函数上,并转化到C++函数执行。

查看源码就会发现,JS的部分是极简的,JS 引擎采用了JerryScript,每一个标签对应了一个C++的Component类。绝大部分功能实际都由C++实现,包括事件注册和触发,页面路由,控件的更新,超时,文件操作,命令行输出等等... 所有API的100%对接不禁让我想起了一个动画片。

进入C++领域后就方便很多了,此时的ACE仍处于用户态,用HDF上的消息机制就能触达内核,无非是再包装一层API的套娃操作。

内置模块
这里有一系列@system.xxx的模块提供了访问APP、Router、Audio、Sensor等等的设备能力。ohos_module_config.h定义了JS框架中模块的别名到模块初始化函数的对应关系。其中app,dfx,router模块是必有的。

// Config information for built-in JS modules of OHOS platform
const Module OHOS_MODULES[] = {
#ifdef ENABLE_MODULE_REQUIRE_TEST
{"sample", InitSampleModule},
#endif
{"app", InitAppModule},
#ifdef FEATURE_MODULE_AUDIO
{"audio", InitAudioModule},
#endif // FEATURE_MODULE_AUDIO
{"dfx", InitDfxModule},
{"router", InitRouterModule},
#ifdef ENABLE_MODULE_CIPHER
{"cipher", InitCipherModule},
#endif
};

实现ace模块
背景知识介绍完了,就可以根据业务的复杂度来依葫芦画瓢的自定义ace模块封装功能,这里为了简化操作,我们直接在内置的app模块上挂载操作。

1. 定义头文件
修改foundation/ace/frameworks/lite/src/core/modules/app_module.h,加入ToggleLed函数并初始化。

namespace OHOS {
namespace ACELite {
class AppModule final : public MemoryHeap {
public:
static JSIValue ToggleLed(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum); void InitAppModule(JSIValue exports)
{
JSI::SetModuleAPI(exports, "getInfo", AppModule::GetInfo);
JSI::SetModuleAPI(exports, "terminate", AppModule::Terminate);
JSI::SetModuleAPI(exports, "toggleLed", AppModule::ToggleLed);
}
} // namespace ACELite
} // namespace OHOS
#endif // OHOS_ACELITE_APP_MODULE_H

2. 调用HDF驱动
在foundation/ace/frameworks/lite/src/core/modules/app_module.cpp中加入,

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h" #define LED_WRITE_READ 1
#define LED_SERVICE "led_service" JSIValue AppModule::ToggleLed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
HILOG_ERROR(HILOG_MODULE_ACE, "led button pressed.");
printf("led button pressed\n"); struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE, 0);
if (serv == NULL)
{
printf("fail to get service %s\n", LED_SERVICE);
return JSI::CreateUndefined();
} static struct HdfDevEventlistener listener = {
.callBack = OnDevEventReceived,c
.priv = (void *)"Service0"}; if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS)
{
printf("fail to register event listener\n");
return JSI::CreateUndefined();
} const char *send_cmd = "toggle LED"; if (SendEvent(serv, send_cmd))
{
printf("fail to send event\n");
return JSI::CreateUndefined();
} if (HdfDeviceUnregisterEventListener(serv, &listener))
{
printf("fail to unregister listener\n");
return JSI::CreateUndefined();
} HdfIoServiceRecycle(serv); return JSI::CreateUndefined();
}

3. 配置HDF头文件路径
修改 foundation/ace/frameworks/lite/src/core/modules/BUILD.gn

include_dirs = [
"presets",
"maplejs",
"//test/lite/testservice/include",
"//vendor/huawei/watchgt/devkit/hal/include",
"//foundation/distributedschedule/interfaces/innerkits/samgr_lite/communication/mpc/transport",
"//foundation/distributedschedule/interfaces/innerkits/samgr_lite/communication/mpc", "//drivers/hdf/lite/include/host",
"$HDF_FRAMEWORKS/ability/sbuf/include",
"$HDF_FRAMEWORKS/core/shared/include",
"$HDF_FRAMEWORKS/core/host/include",
"$HDF_FRAMEWORKS/core/master/include",
"$HDF_FRAMEWORKS/include/core",
"$HDF_FRAMEWORKS/include/utils",
"$HDF_FRAMEWORKS/utils/include",
"$HDF_FRAMEWORKS/include/osal",
"$HDF_FRAMEWORKS/adapter/syscall/include",
"$HDF_FRAMEWORKS/adapter/vnode/include",
]

修改foundation/ace/frameworks/lite/BUILD.gn

config("ace_lite_config") {
include_dirs = [
...
] include_dirs += [
"//drivers/hdf/lite/include/host",
"$HDF_FRAMEWORKS/ability/sbuf/include",
"$HDF_FRAMEWORKS/core/shared/include",
"$HDF_FRAMEWORKS/core/host/include",
"$HDF_FRAMEWORKS/core/master/include",
"$HDF_FRAMEWORKS/include/core",
"$HDF_FRAMEWORKS/include/utils",
"$HDF_FRAMEWORKS/utils/include",
"$HDF_FRAMEWORKS/include/osal",
"$HDF_FRAMEWORKS/adapter/syscall/include",
"$HDF_FRAMEWORKS/adapter/vnode/include",
]
}
shared_library("ace_lite") { public_deps = [
"//base/security/frameworks/crypto_lite/js/builtin:ace_kit_cipher",
"//foundation/graphic/lite/frameworks/surface:surface",
"//foundation/multimedia/frameworks/camera_lite:camera",
"//foundation/multimedia/frameworks/player_lite:player",
"//foundation/multimedia/interfaces/kits/player_lite/js/builtin:audio_api",
"//third_party/bounds_checking_function:libsec_shared",
"//third_party/cJSON:cjson_shared",
"//third_party/jerryscript/jerry-core:jerry-core_shared",
"//third_party/jerryscript/jerry-ext:jerry-ext_shared",
"//third_party/jerryscript/jerry-libm:jerry-libm_shared",
"//third_party/jerryscript/jerry-port/default:jerry-port-default_shared",
"//utils/native/lite/js/builtin:ace_utils_kits",
"//utils/native/lite/timer_task:ace_kit_timer", "//drivers/hdf/lite/manager:hdf_core",
"//drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal",
]
}

4. 编译烧录

python build.py my_hi3516dv300 -b debug

涉及到HDF驱动和ACE框架,就要重新完整烧录镜像文件。

开发界面程序
1. 配置模块接口
前面我们在内置app模块上增加了函数taggleLed,对于DevEco Studio来说是无法直接获取的,所以要先增加api接口。

修改\Huawei\Sdk\js\2.0.1.93\api\smartVision\@system.app.d.ts文件

export default class App {
/**
* Obtains the declared information in the config.json file of an application.
*/
static getInfo(): IAppInfo; /**
* Destroys the current ability.
*/
static terminate(): void; /**
* 翻转Led
*/
static toggleLed(): void;
}


查看更多章节>>>

作者:bluishfish

想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

用鸿蒙开发AI应用(八)JS框架访问内核层的更多相关文章

  1. 用鸿蒙开发AI应用(七)触摸屏控制LED

    [小年答谢,新春送礼]免费抽取1000元京东卡+更多新春好礼~查看详情>>> 目录:前言背景知识编译用户程序框架子系统基于AbilityKit开发的Ability总结 前言上一篇,我 ...

  2. #2020征文-开发板# 用鸿蒙开发AI应用(三)软件篇

    目录: 前言 HarmonyOS 简介 DevEco Device Tool(windows下) 获取源码(切换到ubuntu) 烧录程序(切换回windows) 前言上一篇,我们在 Win10 上用 ...

  3. #2020征文-开发板# 用鸿蒙开发AI应用(一)硬件篇

    目录: 前言 开发板简介 产品特色及功能 产品参数 各个主板功能简介 Hi3516DV300 芯片手册 前言鸿蒙2.0的系统刚开源出来,华为志在打造1+8+N万物互联的全场景智慧生活,不仅是国产操作系 ...

  4. #2020征文-开发板# 用鸿蒙开发AI应用(二)系统篇

    目录: 前言 安装虚拟机 安装 Ubuntu 设置共享文件夹 前言上回说到,我们在一块 HarmonyOS HiSpark AI Camera 开发板,并将其硬件做了一下解读和组装.要在其上编译鸿蒙系 ...

  5. #2020征文-开发板# 用鸿蒙开发AI应用(五)HDF 驱动补光灯

    目录: 前言 硬件准备 HDF 驱动开发 总结 前言上一篇,我们在鸿蒙上运行了第一个程序,这一篇我们来编写一个驱动开启摄像头的红外补光灯,顺便熟悉一下鸿蒙上的 HDF 驱动开发. 硬件准备先查一下原理 ...

  6. 网站开发进阶(十八)js获取html标签中的值

    js获取html标签中的值 项目开发过程中,由于需求所迫,需要获取html标签元素中的内容,下面做一简单总结.以下所讲的示例适用于其它标签元素. 主要包括2中方法获取元素内容: 方法一:.innerT ...

  7. nodejs 实践:express 最佳实践(八) egg.js 框架的优缺点

    nodejs 实践:express 最佳实践(八) egg.js 框架的优缺点 优点 所有的 web开发的点都考虑到了 agent 很有特色 文件夹规划到位 扩展能力优秀 缺点 最大的问题在于: 使用 ...

  8. 微信小程序从零开始开发步骤(八)引入框架WeUI

    首先来看下WeUI的官方介绍: WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一.在微信小程序的开发过程中,涉及到的前端 ...

  9. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍

    2013年04月19日 14:09:37 MJiao 阅读数:4614   深入浅出node.js游戏服务器开发1——基础架构与框架介绍   游戏服务器概述 没开发过游戏的人会觉得游戏服务器是很神秘的 ...

随机推荐

  1. 用python+sklearn(机器学习)实现天气预报数据 模型和使用

    用python+sklearn机器学习实现天气预报 模型和使用 项目地址 系列教程 0.前言 1.建立模型 a.准备 引入所需要的头文件 选择模型 选择评估方法 获取数据集 b.建立模型 c.获取模型 ...

  2. 牺牲速度来节省内存,Redis是觉得自己太快了吗

    前言 正常情况下我们选择使用 Redis 就是为了提升查询速度,然而让人意外的是,Redis 当中却有一种比较有意思的数据结构,这种数据结构通过牺牲部分读写速度来达到节省内存的目的,这就是 zipli ...

  3. [SSL]在线检查服务器HTTPS安全

    https://myssl.com/ SSL/TLS安全评估报告 https://www.ssllabs.com/ssltest/ SSL Server Test HTTPS开启工具(IIS) htt ...

  4. K8s遇到问题解决思路

    问题排查一 从describe去查找相应的deploy/pod/rs/svc [root@k8s-master ~]# kubectl describe po/nginx-f95d765f9-8b6b ...

  5. [工作札记]03: 微软Winform窗体中ListView、DataGridView等控件的Bug,会导致程序编译失败,影响范围:到最新的.net4.7.2都有

    工作中,我们发现了微软.net WinForm的一个Bug,会导致窗体设计器自动生成的代码失效,这个Bug从.net4.5到最新的.net4.7.2都存在,一直没有解决.最初是我在教学工作中发现的,后 ...

  6. JVM 判断对象已死,实践验证GC回收

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 提升自身价值有多重要? 经过了风风雨雨,看过了男男女女.时间经过的岁月就没有永恒不变 ...

  7. 用 UniRx 实现 Timeline 式的异步操作

      没接触 UniRx 之前,我在 Unity 中通常用 Coroutine 或 Callback 来实现异步操作.根据我的任务,一般都是去实现游戏组件的演出,比如:敌方角色图形显示后,我方角色 UI ...

  8. LuoguP5075 [JSOI2012]分零食

    题意 有\(A\)个人,\(m\)个糖,你可以选择一个\(k\),使第\(1\)$k$个人每个人至少得到一个糖,并且第$k+1$\(A\)个人都得不到糖.\(m\)个糖必须给完.对于每个方案都有一个欢 ...

  9. Java 迭代器的使用 Iterator

    Java的集合类可以使用for ... each循环 List Set Queue Deque 我们以List为例 其实一个java编译器并不知道如何遍历一个List 编译器只是把一个for ... ...

  10. innodb锁和事物

    • InnoDB存储引擎支持行级锁,其大类可以细分为共享锁和排它锁两类• 共享锁(S):允许拥有共享锁的事务读取该行数据.当一个事务拥有一行的共享锁时,另外的事务可以在同一行数据也获得共享锁,但另外的 ...