“ACE的单线程异步机制”就是解决这个问题的问题

  HarmonyOS 2提供了两种应用开发语言:Java和JS。Java线程特性能够让多任务并行,充分利用硬件资源开发出高性能的应用。而JS却是一个单线程语言,无法像Java一样创建新的Thread,用JS语言开发是否会导致硬件资源无法充分利用的情况呢?

  本文给大家介绍“ACE JS的单线程异步机制”就是解决这个问题的。然而,说到 “单线程”与“异步”,大家可能会比较疑惑,因为单线程和异步在概念上是冲突的,单线程无法做到多任务并发,也就不会存在异步这种通信机制。

  确实js单线程 ui渲染,JS语言本身是无法实现异步的,但是ACE JS框架却提供了多线程的宿主环境,通过消息通信机制让JS语言有了异步的属性,下面我们来详细描述其原理。

  ACE开发框架

  使用JS开发HarmonyOS应用,使用的开发框架名为ACE(Ability Cross-Platform Environment),该框架适用于手机、平板、智慧屏、智慧表、车机等设备,具备“一次开发,多端部署”的能力。

  ACE框架包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)和平台适配层(Porting Layer),如下图所示:

  activity ui线程_js单线程 ui渲染_线程对渲染的影响

  ​● Application

  应用层表示开发者使用JS UI框架开发的FA应用,这里的FA应用特指JS FA应用。

  ● Framework

  前端框架层主要完成前端页面解析,以及提供MVVM(Model-View-ViewModel)开发模式、页面路由机制和自定义组件等能力。

  ● Engine

  引擎层主要提供动画解析、DOM(Document Object Model)树构建、布局计算、渲染命令构建与绘制、事件管理等能力。

  ● Porting Layer

  适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。

  ACE开发框架的线程模型

  线程对渲染的影响_js单线程 ui渲染_activity ui线程

  ​

  ​

  每个HarmonyOS JS应用,都是通过上图所示的ACE开发框架进行加载渲染的。ACE开发框架包含了JS线程、UI线程、GPU线程、IO线程,并且在ACE框架外还会存在一类后台任务线程。

  其中GPU线程与IO线程主要是ACE框架初始化与页面加载渲染的过程需要的,为ACE框架内部的专有线程,不会被应用直接操作到,应用不需要特别关注;UI线程、JS线程和后台任务线程会与应用开发代码相关,后面着重分析这三个线程的作用和关系。

  ● UI线程:负责应用界面的绘制刷新,与应用的进程号相同,又叫主线程。如果开发JS+JAVA的混合编程,JAVA PA(Particle Ability)的onStart/onConnect等Ability生命周期回调便是运行在主线程,若在这些生命周期回调上执行耗时操作则会导致JS UI的绘制刷新卡住。

  线程对渲染的影响_js单线程 ui渲染_activity ui线程

  ● JS线程:应用的JS代码会被JS引擎解析执行,并运行在JS线程上,而JS又是单线程语言,所以目前我们工程中看到的所有的JS代码都会执行在这个进程下唯一的JS线程上。

  ● 后台任务线程:这里是对ACE框架外部的后台线程的一个统称,并不单指一个线程,也并不唯一。后台任务线程包含了Java PA线程、文件操作API、网络访问API内部实现等相关线程。

  下面我们结合测试代码来看一下这3个线程之间的关系。

  JS线程与UI线程的关系

  为了验证JS线程与UI线程的关系,我们准备了一个实验性质的Demo,主要代码以及运行过程的Log如下:

  首先我们在IDE建立一个Empty Ablity(JS)模板的HelloWorld工程,在生命周期、按钮响应回调方法里增加Log以观察线程情况。刚创建的app.js中Application生命周期默认已经有Log,无需额外添加。

  我们只需要在主界面index.js文件中onInit增加日志:

  console.info('page.default onInit');复制

  然后在index.hml中增加一个button以及会一直进行动画的progress组件:

  

    I'm a button

  activity ui线程_线程对渲染的影响_js单线程 ui渲染

  最后在index.js中增加按钮点击响应事件以及Log,并且尝试sleep阻塞js线程:

<p><pre>
function sleep(delay) {

    for (var t = Date.now(); Date.now() - t 
文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1472
0 评论
368

发表评论

!