更多内容请访问:Harmonyos技术社区https://harmonyos.51cto.com在《技术解析》中介绍了基于JS开发简单业务的方法/JAVA用户界面框架。那么对于复杂的业务,在HarmonyOS当前版本下如何基于JSUI框架进行开发呢?JSUI框架下FA和PA交互的使用场景通常是典型的使用JSUI框架的HarmonyOS应用开发模型如下图1所示:1典型应用开发模型HarmonyOS用户应用包APP由一个或多个Hap包组成.每个Hap可以包含一个或多个能力。Ability分为FeatureAbility(简称FA)和ParticleAbility(简称PA)两种。FA和PA是HarmonyOS应用的基础组件,可以实现特定的业务功能。FA有UI界面,PA没有UI界面。FA有多种展示形式,如常用界面形式的PageAbility,服务卡片形式的Form等,前端界面一般采用JS语言实现。PA支持ServiceAbility和DataAbility。ServiceAbility提供了在后台运行任务的能力,比如处理复杂的后台任务。数据能力用于对外提供统一的数据访问抽象。这两个Abilities一般都是用Java语言实现的。目前HarmonyOSAbility的具体分类信息如下:JSUI框架提供的声明式编程让应用开发变得更简单,但目前HarmonyOSJSAPI还不够丰富,无法处理数据等更复杂的业务。为了处理复杂的业务,保证业务数据和UI的解耦,复杂的逻辑一般在PA即JAVA端实现,界面交互在FA的UI部分即JS端实现,如如图1所示。这就涉及到FA(JS端)和PA(JAVA端)的交互。因此HarmonyOSJSUI框架提供了JSFA(FeatureAbility)调用JAVAPA(ParticleAbility)的机制。传递方法调用、处理数据返回和订阅事件报告的通道。下面我们通过一两个例子来说明该方法涉及的技术原理。FA调用HarmonyOS下的PA机制。接口扩展机制支持ACE开发框架一次性开发和跨平台运行的目标。接口扩展机制用于连接前端应用层和后端平台层。JSUI框架提供了一种自动封装平台能力扩展API的机制,让应用开发者可以方便地调用API来完成从JS端到JAVA端的传输方法调用、处理数据返回、订阅事件上报。图2模块框架模型如图2所示。HarmonyOS目前支持JS作为前端应用开发语言,提供API接口供开发者实现业务逻辑,并将JS层的参数传递给平台层(Native)通过类似的接口扩展机制。同时在平台层提供插件代码(PluginNativecode)供第三方平台实现业务逻辑。JSFrameWork提供了用于传递方法调用、数据流通信和订阅事件回调的API。并通过JsBridge桥接C++和JS,JsBridge主要负责加载JS代码,运行在QJSEngine上,通过全局函数将JS代码桥接到C++,并将C++的结果返回给JS层。QJSEngineQuickJS是一个轻量级和可嵌入的JavaScript引擎,包括模块、异步生成器和代理。ACEFramework透传JS消息到平台层,将JS数据转换为C++类型数据,再通过C++和JAVA的JNI接口类将C++数据传递给JAVA端,并接收JAVA端返回的数据。Native负责对平台层数据进行编解码,根据解码后得到的FunctionName调用第三方开发者的插件代码逻辑。HarmonyOSAPI平台层提供了JAVA端的API接口。开发者在JAVA端实现相应接口的业务逻辑。HarmonyOSJSUI框架下的FA调用PA机制目前FA提供两种调用PA的方式:Ability和InternalAbility:Ability调用方式:具有独立的Ability生命周期,FA使用远程进程通信拉起请求PA服务,适用于基础服务PA有多个FA调用或者PA在后台独立运行的场景。内部Ability调用方式:PA和FA在同一个进程,PA和FA采用内部函数调用方式进行通信,适用于对服务响应时延要求高的场景。该模式下,PA不支持其他FA接入呼叫。这两种调用方式在代码中可以通过abilityType来识别。具体使用差异见下表:FA调用PA注意事项:JS和JAVA端定义的“方法调用”对外开放后,需要保证向前兼容。默认情况下,序列化数据支持的最大数据大小为200KB。如果需要传输大数据,可以使用相应的接口ohos.utils.Parcel.setCapacity()来调整缓冲容量。FA调用PA开发方法下面详细介绍JSFA调用JAVAPA的开发方法。图3FA调用PA开发方法如图3所示,当FeatureAbilityPlugin收到JS调用请求时,系统会根据开发者在JS接口中设置的参数,如指定的abilityType(Ability或内部能力)。处理。开发者在onRemoteRequest()中实现PA提供的业务逻辑,不同的业务通过业务代码来区分。FA端1、ChannelJSAPI提供了以下模块能力:ModuleGroup是一个用来传递方法调用的类,通常由上层应用定义使用,用于调用native中的某个方法。可以通过调用callNative()方法将函数和相应的参数传递给平台层,Native层需要适配相应的逻辑代码。简而言之,ModuleGroup实现JS调用JAVA方法,提供JSAPI如下:√调用PA能力,FeatureAbility.callAbility(OBJECT)EventGroup用于数据流通信,通常用于通知应用层Native事件触发平台层。在应用层调用subscribe()方法注册回调事件启动监控平台,调用unSubscribe()取消平台监控。第三方开发者需要在平台层适配相应的逻辑代码。简而言之,EventGroup实现JAVA回调JS,提供JSAPI如下:订阅PA能力,FeatureAbility.subscribeAbilityEvent(OBJECT,Function)取消订阅PA能力,FeatureAbility.unsubscribeAbilityEvent(OBJECT)2.FeatureAbilityPlugin主要完成方法调用,数据Stream参数传输(codec)、线程切换、JNI转换等处理。主要提供以下两个关键模块:InternalAbilityManager用于对InternalAbility进行管理,包括注册管理等。注册后,InternalAbility和FA共享一个生命周期。ConnectionManagerJS端通过接口扩展机制与JAVA端通信,通过bundleName和abilityName进行关联。PA端PA端提供了以下两类接口:IRemoteObject.onRemoteRequest(int,MessageParcel,MessageParcel,MessageOption)能力调用方法,FA通过远程进程通信拉起请求PA服务。AceInternalAbility.AceInternalAbilityHandler.onRemoteRequest(int,MessageParcel,MessageParcel,MessageOption)内部Ability调用方法,使用内部函数调用与FA通信。Ability调用方法流程图4JSFA调用JAVAPA流程(Ability模式)1.FAJS端指定PA调用方法及相关消息代码和内容,调用PA(订阅PA类似)。设置bundleName、abilityName、abilityType等。2、PAJAVA端响应:通过Ability方法拉上来的PA继承自Ability。当FA请求PA服务时,它会连接到PA。连接成功后,PA在onConnect中返回一个远程对象(RemoteObject),用于FA将PA发送给PA。信息。remote对象实现了onRemoteRequest方法,用于响应FA端的请求。示例代码如下:双数求和FA终端(能力模式)//abilityType:0-Ability;1-InternalAbilityconstABILITY_TYPE_EXTERNAL=0;constABILITY_TYPE_INTERNAL=1;//syncOption(Optional,defaultsync):0-Sync;1-AsyncconstACTION_SYNC=0;constACTION_ASYNC=1;constACTION_MESSAGE_CODE_PLUS=1001;exportdefault{plus:asyncfunction(){varactionData={};actionData.firstNum=1024;actionData.secondNum=2048;//请求参数,abilityName,bundleName,messageCode,abilityType,actionData需要2个入参求和varaction={};action.bundleName='com.example.hiaceservice';action.abilityName='com.example.hiaceservice.ComputeServiceAbility';action.messageCode=ACTION_MESSAGE_CODE_PLUS;action.data=actionData;//使用能力模式action.abilityType=ABILITY_TYPE_EXTERNAL;action.syncOption=ACTION_SYNC;//FA调用PAvarresult=awaitFeatureAbility.callAbility(action);varret=JSON.parse(result);if(ret.code==0){console.info('plusresultis:'+JSON.stringify(ret.abilityResult));}else{console.error('pluserrorcode:'+JSON.stringify(ret.code));}}}PA端(能力模式)publicclassComputeServiceAbilityextendsAbility{privateMyRemoteremote=newMyRemote();//FA在请求PA服务时会连接到PA。连接成功后,需要在onConnect中返回一个远程对象,让FA向PA发送消息@OverrideprotectedIRemoteObjectonConnect(Intentintent){super.onConnect(intent);returnremote.asObject();}//远程对象实现,完成消息请求处理,返回classMyRemoteextendsRemoteObjectimplementsIRemoteBroker{privatestaticfinalintSUCCESS=0;privatestaticfinalintERROR=1;privatestaticfinalintPLUS=1001;MyRemote(){super("MyService_MyRemolelicquepub");}@Reboover(intcode,MessageParceldata,MessageParcelreply,MessageOptionoption){switch(code){//消息代码PLUScasePLUS:{//消息参数解析StringdataStr=data.readString();RequestParamparam=newRequestParam();try{param=ZSONObject.stringToClass(dataStr,RequestParam.class);}catch(RuntimeExceptione){HiLog.error(LABEL,"convertfailed.");}//返回结果设置Map
