#星光计划1.0# HarmonyOS JS FA调用PA新方式 原创 精华
作者:包月东
简介
JS FA调用Java PA一般通过FeatureAbility这种传统方式调用。本文先回顾传统方式,在传统方式的痛点上引入两种新方式。
传统方式
方法说明
常见的JS FA调用Java Pa一般通过以下三个方法
(1) FeatureAbility.callAbility(OBJECT):调用PA能力。
(2) FeatureAbility.subscribeAbilityEvent(OBJECT, Function):订阅PA能力。
(3) FeatureAbility.unsubscribeAbilityEvent(OBJECT):取消订阅PA能力。
1.能常用于同步调用方法
比如:
2.常用于调用异步方法,因为(2)是通过监听的方式实现异步回调,所以在不需要监听时最好调用(3)取消
比如:
实现步骤
在开发过程中应用中常用Internal Ability,现以Internal Ability说明。
Internal Ability需要实现的步骤:
(1)在java中创建java类继承AceInternalAbility,设置setInternalAbilityHandler回调,在回调方法onRemoteRequest中通过命令码code匹配对应的方法名,Parcel中解析方法参数;
(2)在AbilityPackage或者Ability的生命周期对java类对象进行注册和反注册;
(3)在JS中创建对应JS类,调用FeatureAbility.callAbility,FeatureAbility.subscribeAbilityEvent传递命令码和方法参数;
痛点
从实现步骤看出,建立Js FA到Java PA的通道,比较繁琐,以下操作如果能够由系统自动完成,那么用户只关注java端方法实现、js端调用,使用就简便很多。
(1)进行注册,反注册;
(2)解析方法名,方法参数;
(3)返回值需要通过parcel进行回传;
注意点
-
java给js端返回结果(回消息)时,仅支持String。
虽然reply拥有writeInt,writeBoolean等等方法,但目前支持writeString。
-
被调用的java方法运行在非UI线程。
通过在onRemoteRequest处打印当前线程是否UI线程,我们可以得出js调用过来在java代码处是非UI线程的,如果在此处进行UI操作,就会有一定的风险。
如果存在UI操作,可以context.getUITaskDispatcher().syncDispatch(Runnable)或者new EventHandler(EventRunner.getMainEventRunner()).postTask方式处理。
-
Parcel的大小是200kb,如果超过200kb(实际没这么多),会抛异常,如下:
官网对于Parcel的介绍
The default capacity of a Parcel instance is 200KB. If you want more or less, use setCapacity(int) to change it.
Note: Only data of the following data types can be written into or read from a Parcel: byte, byteArray, short, shortArray, int, intArray, long, longArray, float, floatArray, double, doubleArray, boolean, booleanArray, char, charArray, String, StringArray, PlainBooleanArray, Serializable, Sequenceable, and SequenceableArray.
解决办法:增大parcel的容量
-
CallAbility的TF_ASYNC 与Subscribe的区别
虽然两个看上去都像异步,但是从调用上看CallAbility的TF_ASYNC仍然是同步的,只是没有使用onRemoteRequest的reply方式进行回传。
新方式一: js2java-codegen
从上面实现java,js通信的步骤可以看出,我们在java端对js传过来的方法、方法参数进行解析,解析完值后如果有返回值还需要通过Parcel回传。要是能够系统自动帮我们实现对方法名,方法参数的解析,那就省去一大部分工作。
正好,鸿蒙推出了js2java-codegen这个注解。
条件
Toolchains的2.2.0.3以上
实现步骤
-
在module下的gradle开启js2java-codegen。
注:jsOutputDir的路径一定要配置好,否则下面的编译阶段会报以下错误。
-
编写提供给js调用的java类。
解释:
1)使用InternalAbility注解java类,注解处理器会根据此类生成对应JsBridgeXStub.java和JsBridgeX.js,这两个类帮我们建立了通信通道;
2)属性registerTo设为想要注册到的Ability类的全称。因为开发中我们可能用到context相关的方法,比如启动一个Ability。这里的registerTo和下面的@ContextInject配合使用,使被修饰的abilityContext指向MainAbility;
-
编译
点击Build -> Build HAP(s)/APP(s) -> Build HAP(s),js2java-codegen工具会为我们生成通信通道,JsBridgeXStub.java和JsBridgeX.js。
-
JsBridgeXStub.java
点开JsBridgeXStub.java,我们看到,在onRemoteRequest这里仍然是方法名,方法参数解析。
-
JsBridgeX.js
我们看到,这里使用了FeatureAbility.callAbility,action的data属性中包含了要调用的方法名(add)和方法参数(a,b)。
-
-
使用
注意点
-
返回值从abilityResult属性获取,如上ret.abilityResult。
-
只支持同步方法FeatureAbility.callAbility,不支持FeatureAbility.subscribeAbilityEvent、FeatureAbility.unsubscribeAbilityEvent。从目前官网资料看,生成的方法都是FeatureAbility.callAbility方式。
-
void方法,private,protected,default访问权限的方法不会生成。
-
生成对应的js方法都是async的。
-
非public方法通过编译不会暴露给js,即生成的js代码没有对应方法,如果想要public方法也不想暴露给js用,可以使用**@ExportIgnore**。
-
只支持文件中public的顶层类,不支持接口类和注解类。
-
跟传统的调用方式不同,js端必须new 一个实例,通过实例调用方法。
新方式二:LocalParticleAbility
不同于上面的js2java-codegen这种方式,LocalParticleAbility在系统内部已经建立好通道,不需要编译生成额外的代码,在java端实现,在js端调用就行,比js2java-codegen更加简单。
条件
从API Version 6 开始支持。
实现步骤
-
java端实现接口LocalParticleAbility,添加方法。
注:这里列举了同步和异步的两种方式,异步需要LocalParticleAbility.Callback的reply方法返回。
-
注册。
-
js端调用。
a) 创建LocalParticleAbility对象
b)调用方法
- 调用同步方法
- 调用异步方法
从上面可以看出LocalParticleAbility既支持同步又支持异步,弥补了js2java-codegen的不足。
注意点
- 目前从官网中js端的createLocalParticleAbility找不到,目前调试不行。
- API Version 6 开始支持。
- 需要注册和反注册。
总结
- 传统JS FA的调用方式需要关注方法名,方法参数的传递解析,比较复杂,后续大概率会被LocalParticleAbility这种简洁方式替换。
- js2java-codegen提供了APT技术帮我们生成通道代码,但是受限于不能实现异步,函数必须有返回值等,实用性不强。
- LocalParticleAbility优势很大,是未来的方向,目前虽然提供了文档,但是在DevEco Studio 3.0端 SDK 6仍然不能成功。
项目地址
https://gitee.com/freebeing/facallpa.git
参考
https://developer.harmonyos.com/cn/docs/documentation/doc-references/parcel-0000001054519018
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-js2java-codegen-0000001171039385
https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/js2java-codegen
更多原创内容请关注:开鸿 HarmonyOS 学院
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,共建鸿蒙生态,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
回顾和新的方式都讲解的很详细,值得好好学习。
正在学习这部分,受教了,全面的解析
看完了,真的全面