HarmonyOS4.0从零开始的开发教程03初识ArkTS开发语言(中)

HarmonyOS(二)初识ArkTS开发语言(中)之TypeScript入门

浅析ArkTS的起源和演进

1 引言

Mozilla创造了JS,Microsoft创建了TS,Huawei进一步推出了ArkTS。

从最初的基础的逻辑交互能力,到具备类型系统的高效工程开发能力,再到融合声明式UI、多维状态管理等丰富的应用开发能力,共同组成了相关的演进脉络。

ArkTS是HarmonyOS优选的主力应用开发语言。它在TypeScript(简称TS)的基础上,扩展了声明式UI、状态管理等相应的能力,让开发者可以以更简洁、更自然的方式开发高性能应用。TS是JavaScript(简称JS)的超集,ArkTS则是TS的超集。ArkTS会结合应用开发和运行的需求持续演进,包括但不限于引入分布式开发范式、并行和并发能力增强、类型系统增强等方面的语言特性。本期我们结合JS和TS以及相关的开发框架的发展,为大家介绍ArkTS的起源和演进思路。

2 JS

JS语言由Mozilla创造,最初主要是为了解决页面中的逻辑交互问题,它和HTML(负责页面内容)、CSS(负责页面布局和样式)共同组成了Web页面/应用开发的基础。随着Web和浏览器的普及,以及Node.js进一步将JS扩展到了浏览器以外的环境,JS语言得到了飞速的发展。在2015年相关的标准组织ECMA发布了一个主要的版本ECMAScript 6(简称ES6),这个版本具备了较为完整的语言能力,包括类(Class)、模块(Module)、相关的语言基础API增强(Map/Set等)、箭头函数(Arrow Function)等。从2015年开始,ECMA每年都会发布一个标准版本,比如ES2016/ES2017/ES2018等,JS语言越来越成熟。

为了提升应用的开发效率,相应的JS前端框架也不断地涌现出来。其中比较典型的有Facebook发起的React.js,以及个人开发者尤雨溪发起的Vue.js。React和Vue的主要出发点都是将响应式编程的能力引入到应用开发中,实现数据和界面内容的自动关联处理。具体的实现方式上,React对JS做了一些扩展,引入了JSX(JavaScript XML)语法,可以将HTML的内容统一表示成JS来处理;Vue则是通过扩展的模板语法(Template)的方式来处理。

下面通过两个示例,为大家简要介绍React和Vue。(**示例来源于w3schools网站:**https://www.w3schools.com/whatis/)

1. React示例

图1 React示例

img

以上代码描述了React如何在指定的页面元素(id为id01的div元素)中改变相应的字符串内容(从"Hello World!“到"Hello John Doe!”)。其中第5行的ReactDOM.render()是React JS库提供的一个方法,它可以将相应的内容刷新到指定的HTML元素中。第6行是符合JSX语义的一段代码,它包含了一个类似HTML结构的字符串(

),以及一个表达数据绑定语义的字段({name}),会关联到第4行定义的name变量。通过这种方式,JSX把HTML的语义以及数据绑定机制和JS语言结合起来,可以方便地在JS语言中使用。

2. Vue示例

图2 Vue示例

img

以上Vue示例代码也描述了类似的功能。其中第13行是类似HTML的语法,描述一个id为app的div页面元素,其中的{{message}}是数据绑定的语义,在Vue中表示为Template。第69行是JS代码,描述了一个Vue对象,对应了上述的app页面元素以及所需的数据变量message的内容信息。第11~13行则是JS函数,它改变message变量的值为"John Doe"。执行这个函数时Vue会自动实现相应的UI界面刷新。

如上所示,React和Vue所表达的能力是类似的,不过侧重点稍微有所不同。React主要是基于JSX的语法,将类HTML的语法融合到JS语言中;Vue则是基于Template机制,在HTML的基础上扩展相应的语义。当然,上面这两个例子只是简要地描述了React和Vue的基础信息,更详细的语法以及CSS相关的使用等都没涉及。

从运行时的维度来看,基于React以及Vue的应用都可运行在Web引擎上。为了进一步提升相应的性能体验,2015年Facebook在React基础上推出了React Native, 在渲染架构上没有采用传统的Web引擎渲染路径,而是桥接到相应OS平台的原生UI组件上。2019年Facebook引入全新实现的JS引擎Hermes,并推出一系列架构改进来进一步提升React Native的性能体验。2016年阿里巴巴开源的Weex则是基于Vue做了一些类似的改进,也是采用了桥接到原生UI组件的渲染路径。

3 TS

随着JS生态的发展,如何更有效地支撑大型的应用工程开发变成了一个重要的课题。大型的应用工程一般会涉及较复杂的代码以及较多的团队协作,对语言的规范性,模块的复用性、扩展性以及相关的开发工具都提出了更高的要求。为此,Microsoft在JS的基础上,创建了TS语言,并在2014年正式发布了1.0版本。TS主要从以下几个方面做了进一步的增强:

  • 引入了类型系统,并提供了类型检查以及类型自动推导能力,可以进行编译时错误检查,有效的提升了代码的规范性以及错误检测范围和效率。
  • 在类型系统基础上,引入了声明文件(Declaration Files)来管理接口或其他自定义类型。声明文件一般是以d.ts的形式来定义模块中的接口,这些接口和具体的实现做了相应的分离,有助于各模块之间的分工协作。另外,TS通过接口,泛型(Generics)等相关特性的支持,进一步增强了设计复杂的框架所需的扩展以及复用能力。

在工具层面,TS也有相应的编辑器、编译器、IDE(Integrated Development Environment)插件等相关的工具,来进一步提升开发效率。

TS在兼容JS生态方面也做了较好的平衡,TS应用通过相应编译器可以编译出纯JS应用,可以在标准的JS引擎上运行。同时,TS定位为JS的超集,即JS应用也是合法的TS应用。此外,在标准层面上,TS兼容ECMA的相应标准,并维护那些还未成为ECMA标准的新特性。

4 ArkTS

如上所述,基于JS的前端框架以及TS的引入,进一步提升了应用开发效率,但依然存在一些不足。

从开发者维度来看:

写一个应用需要了解三种语言(JS/TS、HTML和CSS)。这对Web开发者相对友好,但对非Web开发者来说,负担较重。

从运行时维度来看:

  • 在语言运行时方面,尽管TS有了类型的加持,但也只是用于编译时检查,然后通过TS Compiler转成JS,运行时引擎还是无法利用到基于类型系统的优化。
  • 在渲染方面,主流Web引擎由于本身复杂度以及历史原因,性能、资源占用方面与常见OS原生框架都有一定的差距,尤其在移动平台上。React Native通过渲染架构的改进一定程度上提升了性能体验,但在平台渲染效果和能力的一致性,以及JS语言性能等方面还是存在一定的不足。

Google在2018年底推出的Flutter则走了另外一条路,结合新的语言Dart,引入新的声明式开发范式,基于Skia的自绘制引擎构建可跨平台的独立的渲染能力。这是一种较为创新的方案,不过也有几点不足:

  • Dart语言生态。尽管Dart语言2011年就已推出,传闻其目标是取代JS,但整个生态还是非常弱小,Dart语言发布7年后随着Flutter的推出才有所改善。整体而言,Dart和主流语言生态相比还是有非常大的差距。
  • 开发范式。Flutter暴露了很多细粒度的Widget接口,整体开发的简洁度,开发门槛,尤其是和Apple推出的SwiftUI相比,存在一定的差距。

有意思的是,Google在2021年又推出了新的开发框架Jetpack Compose,结合了Kotlin的语言生态,设计了新的声明式UI开发范式。

2019年,我们在思考如何构建新的应用开发框架的时候,从以下几个维度进行了重点考虑:

  • 语言生态
  • 开发效率
  • 性能体验
  • 跨设备/跨平台能力

由于JS/TS有比较完善的开发者生态,语言也比较中立友好,有相应的标准组织可以逐步演进,JS/TS语言成了比较自然的选择。以JS/TS为基础,在开发框架的维度,我们做了如下的架构演进设计:

  • 通过基于JS扩展的类Web开发范式,来支持主流的前端开发方式。同步的,在运行时方面,通过渲染引擎的增强(平台无关的自绘制机制、声明式UI后端设计、动态布局/多态UI组件等),语言编译器和运行时的优化增强(代码预编译、高效FFI-Foreign Function Interface、引擎极小化等),进一步提升相关的性能体验,并可部署到不同设备上(包括百KB级内存的轻量设备)。另外,通过平台适配层的设计,构建了跨OS平台的基础设施。
  • 通过基于TS扩展的声明式UI开发范式,提供了更简洁更自然的开发体验。在运行时方面,在上述的基础上,结合语言运行时的类型优化,以及渲染运行时的扁平化流水线技术等,进一步提升性能体验。

图3 ArkUI开发框架

img

图3描述了ArkUI开发框架的整体架构,其中,基于TS扩展的声明式UI范式中所用的语言就是ArkTS。下面结合一个具体示例,从应用开发视角简单介绍下基于ArkTS的全新声明式开发范式。

如图4所示的代码示例,UI界面会显示两段文本和一个按钮,当开发者点击按钮时,文本内容会从’Hello World’变为‘Hello ArkUI’。

图4 ArkTS声明式开发范式

img

这个示例中所包含的ArkTS声明式开发范式的基本组成说明如下:

  • 装饰器

用来装饰类、结构体、方法以及变量,赋予其特殊的含义,如上述示例中 @Entry 、 @Component 、 @State 都是装饰器。具体而言, @Component 表示这是个自定义组件; @Entry 则表示这是个入口组件; @State 表示组件中的状态变量,此状态变化会引起 UI 变更。

  • 自定义组件

可复用的 UI 单元,可组合其它组件,如上述被 @Component 装饰的 struct Hello。

  • UI 描述

声明式的方式来描述 UI 的结构,如上述 build() 方法内部的代码块。

  • 内置组件

框架中默认内置的基础和布局组件,可直接被开发者调用,比如示例中的 Column、Text、Divider、Button。

  • 事件方法

用于添加组件对事件的响应逻辑,统一通过事件方法进行设置,如跟随在Button后面的onClick()。

  • 属性方法

用于组件属性的配置,统一通过属性方法进行设置,如fontSize()、width()、height()、color() 等,可通过链式调用的方式设置多项属性。

从UI框架的需求角度,ArkTS在TS的类型系统的基础上,做了进一步的扩展:定义了各种装饰器、自定义组件和UI描述机制,再配合UI开发框架中的UI内置组件、事件方法、属性方法等共同构成了应用开发的主体。在应用开发中,除了UI的结构化描述之外,还有一个重要的方面:状态管理。如上述示例中,用 @State 装饰过的变量 myText ,包含了一个基础的状态管理机制,即 myText 的值的变化会自动触发相应的 UI 变更 (Text组件)。ArkUI 中进一步提供了多维度的状态管理机制。和 UI 相关联的数据,不仅可以在组件内使用,还可以在不同组件层级间传递,比如父子组件之间,爷孙组件之间,也可以是全局范围内的传递,还可以是跨设备传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递。开发者可以灵活的利用这些能力来实现数据和 UI 的联动。

总体而言,ArkUI开发框架通过扩展成熟语言、结合语法糖或者语言原生的元编程能力、以及UI组件、状态管理等方面设计了统一的UI开发范式,结合原生语言能力共同完成应用开发。这些构成了当前ArkTS基于TS的主要扩展。

ArkUI完整的开发范式可参考这里:

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/arkui-overview-0000001281480754

5 下一步演进

接下来,除UI框架需求之外,ArkTS也会结合应用开发及运行的其他方面需求持续演进:

1. 更完善的类型系统

我们已经设计并实现了专门运行时,利用ArkTS的类型输入,在程序执行一开始就获得较高的运行性能(不像其它传统JS引擎需要预热才能获取高性能)。但是目前的类型系统在运行时的设计上仍然考虑了兼容模式,即在运行时,当对象类型发生变化时会走Bailout机制,以使程序在类型不匹配时仍能正常运行。一种更极致的方式是:引入一种特定模式来支持确定类型的表达,当开发者可以明确类型时,提供相应的信息,这样运行时可以通过针对性设计,进一步提升性能体验。另外,ArkTS将来也会在类型系统中拓展一些新的类型,在与运行时结合的优化中会提供更好的性能体验。

2. 更灵活的并行化处理

目前的移动设备基本都是多核设备(包括同一配置的多核以及不同配置的大小核),有些设备还会携带多种计算芯片(CPU/GPU/NPU/…)。语言在并发特性上如何充分应用多核设备甚至异构芯片是一个重要的课题。目前我们采用的仍然是业界常见的类Actor模型的并发接口——Worker,它弥补了Actor模型的些许劣势,即允许用户转移和共享大量的Buffer以避免通信时拷贝的开销。但是开发者仍需自己去管理Worker的生命周期,利用Worker也不能非常方便地触发一个异步并行任务。我们已经在尝试在Actor模型上封装一种任务接口,方便用户更容易利用多核触发异步并行任务。我们也一直在关注Swift、Dart、Kotlin、Go这些语言并发特性的发展和运行时的实现,ArkTS的特定模式中静态类型模型的引入也会给并发机制带来更多高性能实现的可能性,比如对象的冻结、所有权转移、值语义等等。我们将持续致力于提供简洁高效的并发API,帮助应用开发者更容易开发出高性能的应用。

当然,ArkTS以及ArkUI开发框架还很年轻,还有很多其它方面也会持续演进,比如UI自定义能力的进一步完善,语言运行时以及跨语言交互的进一步优化,跨OS平台能力的扩展,分布式开发范式等等。

作为应用生态的底座,应用开发框架的创新永无止境。我们希望和广大的开发者一起,持续围绕着开发效率、运行体验、跨设备/跨平台等相关方面一起合作,一起创新,共建繁荣的应用生态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/211960.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

13年测试老鸟总结,性能测试常遇问题+解决方案+分析...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、内存溢出 1&a…

Cmkae外部依赖管理

文章目录 一、cmake依赖管理介绍二、源码依管理1. FetchContent与find_package进行集成 2. CPM3. git submodule附加: address_sanitizer 和 undefined sanitizer 一、cmake依赖管理介绍 CMake 是跨平台的构建系统,支持 C/C、Objective-C、Fortran 等多种…

Python第三次练习

Python 一、如何判断一个字符串是否是另一个字符串的子串二、如何验证一个字符串中的每一个字符均在另一个字符串中出现三、如何判定一个字符串中既有数字又有字母四、做一个注册登录系统 一、如何判断一个字符串是否是另一个字符串的子串 实现代码: string1 inp…

外包干了2个多月,技术明显有退步了。。。。。

先说一下自己的情况,本科生,19年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

JVM:强软弱虚四种引用

下面依次解释五种引用 一、强引用 把一个对象赋值给一个引用变量,就相当于把这个对象的强引用放到变量中。 只要对象可达, GC一定不会回收这个对象(A1) 二、软引用 当一个对象(A2)没有强引用时&#xff…

Rust UI开发(五):iced中如何进行页面布局(pick_list的使用)?(串口调试助手)

注:此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库,用于为rust语言程序构建UI界面。 这是一个系列博文,本文是第五篇,前四篇链接: 1、Rust UI开发(一):使用iced构建UI时…

网络安全(一)--网络环境构成,系统的安全

2. 网络攻防环境 目标 了解攻防环境构成了解入侵检测系统(平台)的部署位置 2.1. 环境构成 2.1.1. 环境框图 一个基本的网络攻防实验环境包括:靶机、攻击机、入侵检测分析系统、网络连接四部分组成。 一个基础的网络攻防实验环境需要如下…

【SpringCloud】通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题

文章目录 前言1.第一次尝试1.1服务被调用方更新1.2压测第一次尝试1.3 问题分析1.4 同步的不是最新列表 2.第二次尝试2.1调用方过滤下线服务2.2压测第二次尝试2.3优化 写到最后 前言 在上文的基础上,通过压测的结果可以看出,使用DiscoveryManager下线服务…

EasyExcel如何读取全部Sheet页数据方法

一、需求描述 Excel表格里面大约有20个sheet页,每个sheet页65535条数据,需要读取全部数据,并导入至数据库。 找了好多种方式,EasyExcel比较符合,下面看代码。 二、实现方式 采用EasyExcel框架的doReadAll()方法 1、…

Linux驱动开发学习笔记2《LED驱动开发试验》

目录 一、Linux下LED灯驱动原理 1.地址映射 二、硬件原理图分析 三、实验程序编写 1.LED 灯驱动程序编写 2.编写测试APP 四、运行测试 1.编译驱动程序和测试APP (1)编译驱动程序 (2)编译测试APP 2.运行测试 一、Linux下…

redis应用-分布式锁

目录 什么是分布式锁 分布式锁的基本实现 引入过期时间 引入校验id 引入lua 引入看门狗 引入redlock算法 什么是分布式锁 在一个分布式系统中,也会涉及到多个节点访问同一个公共资源的情况,此时就需要通过锁来做互斥控制,避免出现类似于"线程安全"的问题. 而…

Selenium无头模式容易遇到的坑

在无头模式下,我们看不到浏览器的操作,但是selenium无头模式的浏览器向服务器发送的请求头和正常模式下还是有点区别的,这就导致了一些网站会检测到我们是用selenium来访问的,从而导致一些问题 下面就是我在使用selenium无头模式时…

134. 加油站(贪心算法)

根据题解 这道题使用贪心算法,找到当前可解决问题的状态即可 「贪心算法」的问题需要满足的条件: 最优子结构:规模较大的问题的解由规模较小的子问题的解组成,规模较大的问题的解只由其中一个规模较小的子问题的解决定&#xff…

SpringSecurity(五)

深入理解HttpSecurity的设计 一、HttpSecurity的应用 在前章节的介绍中我们讲解了基于配置文件的使用方式,也就是如下的使用。 也就是在配置文件中通过 security:http 等标签来定义了认证需要的相关信息,但是在SpringBoot项目中,我们慢慢脱离…

SpringBoot读取properties文字乱码问题及相关问题

问题:在idea的编辑器中properties文件一般用UTF-8编码,SpringBoot2读取解码方式默认不是UTF-8,当值出现中文时SpringBoot读取时出现了乱码。 解决方式1:在SpringBoot框架层面解决,在配置类注解上添加encoding属性值为…

Linux---逻辑卷管理

本章主要介绍逻辑卷的管理。 了解什么是逻辑卷创建和删除逻辑卷扩展逻辑卷缩小逻辑卷逻辑卷快照的使用 前面介绍了分区的使用,如果某个分区空间不够,想增加空间是非常困难的。所以,建议尽可能使用逻辑卷而非普通的分区,因为逻辑卷…

localhost工具:本地代码的远程之路 | 京东云技术团队

在日常的开发过程中,本地代码远程调试一直是最理想的开发状态。本文通过介绍京东集团内开发的一个轻量简单的小工具”localhost”,从多角度的方案思考,到原理介绍,到最终的方案落地,在开发阶段发现问题,解决…

【数据结构高阶】AVL树

上期博客我们讲解了set/multiset/map/multimap的使用,下面我们来深入到底层,讲解其内部结构: 目录 一、AVL树的概念 二、AVL树的实现 2.1 节点的定义 2.2 数据的插入 2.2.1 平衡因子的调整 2.2.1.1 调整平衡因子的规律 2.2.2 子树的旋…

识别低效io引起的free buffer waits

产生事发时间段的awr报告 Top 5 wait events 这里重点关注: 1.free buffer waits 2.enq_HW-contention 3.enq:tx-row lock contention enq:HW-contention属于水位线的争用,已经透过alter table allocate extent,提前分配空间,这里不做讨论 …

C++——红黑树

作者:几冬雪来 时间:2023年12月7日 内容:C——红黑树讲解 目录 前言: 红黑树的概念: 红黑树的性质: 红黑树的路径计算: 最长路径和最短路径: AVL树与红黑树的区别&#xff…