龙岩同城网

回复:0 发表于 2022-1-3 14:16
发表于 2022-1-3 14:16:08 | 显示全部楼层 |阅读模式

HarmonyOS JS应用开发需要关注哪些线程? [复制链接]

HarmonyOS JS应用开发需要关注哪些线程?

HarmonyOS 2提供了对两种开发语言的支持:Java和JavaScript(下文简称JS)。从事过Android开发的同学对Java都很熟悉了,其多线程特性能够让多任务并行执行,充分利用硬件资源开发出高性能的应用。在HarmonyOS 2上,JS目前无法像Java一样直接创建新的Thread,那么使用JS语言开发HarmonyOS应用是否会遇到硬件资源无法充分利用的情况呢?

虽然使用JS语言目前无法直接创建新的Thread,但是HarmonyOS的JS UI框架提供了多线程的宿主环境,可以帮助应用开发丰富的业务逻辑。在开发HarmonyOS 2应用时,开发者除了需要了解JS线程外,还需要关注哪些线程?这些线程之间的关系又是什么样的?下面让我们一起来研究一下HarmonyOS开发者指南

一、HarmonyOS的JS UI框架

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

Application

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

Framework

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

Engine

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

Porting Layer

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

二、JS UI框架的线程模型
每个HarmonyOS JS应用,都是通过JS UI框架进行加载渲染的。HarmonyOS的JS UI框架包含了JS线程、UI线程、GPU线程、IO线程这4个线程,并且在JS UI框架外还会存在一类后台任务线程。

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

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

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

后台任务线程:这是对JS UI框架外部的后台线程的一个统称,并不单指一个线程,也并不唯一。它包含了Java PA中onRemoteRequest()业务逻辑的执行线程、文件操作API、网络访问API内部实现等相关线程。

下面我们结合测试代码来看一下这3个应用开发需要关注的线程之间的关系。

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

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

我们需要在自动创建的MainAbility.java中onStart/onTouchEvent回调函数增加HiLog打印:

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

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

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

我们将应用运行起来,点击一次按钮,会发现progress组件动画并不会因为onButtonClick阻塞了1秒钟而有任何暂停,我们一起来分析一下这个过程中的Log:从输出的Log中,时间点后面跟着的便是我们执行日志的代码行所在的进程号与线程号,刚才我们增加的日志均在15870这个进程下,这个进程下又存在15870线程以及18938线程。其中15870与进程号相同,这便是我们说的UI线程;我们在.js文件中增加的日志全都会在18938线程上打印出来,这个便是JS线程。

在应用初始化时,首先进入MainAbility.java的onStart生命周期回调,然后才进入AceApplication、Page等JS代码逻辑;应用初始化完毕后,UI线程上便会持续刷新progress组件的动画,当用户点击按钮触发onButtonClick阻塞1秒时,因为阻塞的仅仅是JS线程,所以UI线程上progress组件的动画刷新并不会有任何影响,还是在持续刷新。所以我们可以确定JS线程与UI线程的相互调用应该是通过某种消息机制完成的,而不是阻塞式的调用。

四、JS线程与后台任务线程的关系
JS UI框架提供了JS FA(Feature Ability)调用Java PA(Particle Ability)的机制,该机制提供了一种通道来传递方法调用、处理数据返回以及订阅事件上报的机制,Java PA运行在一个独立的后台任务线程,可以支撑应用开发多线程的业务逻辑。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发表新贴 返回顶部