JS FA(Feature Ability)调用PA (Particle Ability)是使用基于JS扩展的类Web开发范式的方舟开发框架所提供的一种跨语言能力调用的机制,用于建立JS能力与Java能力之间传递方法调用、处理数据返回以及订阅事件上报的通道。开发者可以使用FA调用PA机制进行应用开发,但直接使用该机制需要开发者手动撰写大量模板代码,且模板代码可能与业务代码相互耦合,使得代码可维护性和可读性较差。
想要提升开发效率,开发者可以在DevEco Studio环境中借助js2java-codegen工具自动生成JS FA调用PA代码(目前仅支持InternalAbility调用方式),快速完成FA调用PA应用的开发。开发者只需添加简单的配置与标注即可利用该工具完成大部分FA调用PA模板代码的编写,同时也有效地将业务代码与模板代码相互分离,使代码具有更好的可维护性与可读性。
说明
关于JS FA调用PA的详细介绍,请参考JS FA如何调用PA。
js2java-codegen工具简介
js2java-codegen是工具链提供的自动生成JS FA调用PA代码的辅助开发工具。它可以根据用户源码生成FA调用PA所需的、与用户编写的业务代码相互分离的模板代码。
js2java-codegen工具所支持的FA调用PA实现方式为InternalAbility类型,目前尚不支持Ability类型。开发者完成设置后只需编写包含实际业务逻辑的InternalAbility类和需要注册的Ability类,并在InternalAbility类中加上对应注解,js2java-codegen即可在编译过程中完成FA调用PA通道的建立。之后,开发者只需在JS侧调用由js2java-codegen工具生成的JS接口即可调用Java一侧的能力。
js2java-codegen工具所生成的模板代码包含Java代码和JS代码。其中Java代码会被直接编译成字节码文件,并且对应Ability类中会被自动添加注册与反注册语句,开发者无需关注;而JS代码则需要用户手动调用,因此开发者需要在编译前设置好JS代码的输出路径。
从HarmonyOS SDK中Toolchains的2.2.0.3版本开始支持该功能。
注解使用说明
js2java-codegen工具通过注解来获取信息并生成开发者所需的代码。因此用户如果想使用该工具辅助开发,则需要了解以下三种注解的用法。
@InternalAbility注解
类注解,用于被使用作InternalAbility的、包含实际业务代码的类(简称InternalAbility类)。只支持文件中public的顶层类,不支持接口类和注解类。
包含一个参数:registerTo,值为需要注册到的Ability类全名。具体用例可见Java侧代码编写部分。
用例如下,代表Service类是一个InternalAbility类,注册到位于com.example包中的、名为Ability的Ability类。
@InternalAbility(registerTo = "com.example.Ability") public class Service{}
@ExportIgnore注解
方法注解,用于InternalAbility类中的某些方法,表示该方法不暴露给JS侧来调用。仅对public方法有效。
用例如下,代表service方法不会被暴露给JS侧。
@ExportIgnore public int service(int input) { return input; }
@ContextInject注解
用于AbilityContext上的注解。该类由HarmonyOS的Java API提供,开发者可通过它获取API中提供的信息。
用例如下,代表开发者可以借助abilityContext对象获取API中提供的信息。
@ContextInject AbilityContext abilityContext;
新建工程
想要体验工具生成模板代码的功能,可使用DevEco Studio新建一个包含JS前端的简单手机项目,并用其开发一个简单的FA调用PA应用。
工具开关与编译设置
在需要进行代码生成的模块下的build.gradle中控制开关和进行编译设置。想要快速验证功能,可选择修改entry模块的build.gradle,通过entry模块进行验证。
编译参数位于ohos -> defaultConfig中,只需添加如下设置即可。开发者需在此处设置JS模板代码生成路径,即'jsOutputDir'对应的值。
// 在文件头部定义JS模板代码生成路径 def jsOutputDir = project.file("src/main/js/default/generated").toString() // 在ohos -> defaultConfig中设置JS模板代码生成路径 javaCompileOptions { annotationProcessorOptions { arguments = ["jsOutputDir": jsOutputDir] // JS模板代码生成赋值 } }
工具开关位于ohos中,只需添加如下设置即可。值设为true则启用工具,false或不进行配置则不启用工具。
compileOptions { f2pautogenEnabled true // 此处为启用js2java-codegen工具的开关 }
Java侧代码编写
模板代码的生成需要开发者提供用于FA调用的PA,因此开发者需要自己编写InternalAbility类,然后在类上加@InternalAbility注解,registerTo参数设为想要注册到的Ability类的全称。(Ability类可使用项目中已有的MainAbility类,或创建新的Ability类)
注意,InternalAbility类中需要暴露给FA来调用的方法只能是public类型的非静态非void方法,如若不是则不会被暴露。
一个简单的InternalAbility类实现如下,文件名为Service.java,与MainAbility类同包,用注解注册到MainAbility类。类里面包含一个add方法作为暴露给JS FA来调用的能力,实现了两数相加的功能,入参为两个int参数,返回值为两数的和。
package com.example.myapplication; import ohos.annotation.f2pautogen.InternalAbility; @InternalAbility(registerTo = "com.example.myapplication.MainAbility") // 此处registerTo的参数为项目中MainAbility类的全称 public class Service { public int add(int num1, int num2) { return num1 + num2; } }
编译
js2java-codegen工具在编译过程中会自动被调用,自动生成模板代码并完成整个通道建立的过程。
点击菜单栏中的Build -> Build HAP(s)/APP(s) -> Build HAP(s),即可完成对项目的编译,同时js2java-codegen工具会在编译过程中完成FA调用PA通道的建立。
编译过程会生成Java和JS的模板代码。其中JS的模板代码位于开发者在编译设置中设置的路径,名称与InternalAbility类的名称相对应;而Java的模板代码位于entry > build > generated > source > annotation > debug > InternalAbility类同名包 > InternalAbility类名+Stub.java,而该类的调用语句会被注入到MainAbility类的字节码当中。以下两图为生成的模板代码示例。
Java模板代码示例
JS模板代码示例
JS侧代码编写
为了简易直观地检验工具生成的代码的可用性,开发者可以通过修改entry > src > main > js > default > pages > index > index.js来调用Java侧的能力并在前端页面展示效果。
可通过import方式引入JS侧FA接口,例如import Service from '../../generated/Service.js';(from后的值需要与编译设置中的路径进行统一。生成的JS代码文件名及类名与InternalAbility类名相同。)
一个简单的index.js页面实现如下,调用了JS侧接口,传入了1和10两个参数,并把返回的结果打印在title中,这样只要运行该应用就可以验证FA调用PA是否成功。
import Service from '../../generated/Service.js'; // 此处FA路径和类名对应之前的jsOutput路径以及InternalAbility的名字 export default { data: { title: "Result:" }, onInit() { const echo = new Service(); // 此处新建FA实例 echo.add(1,10) .then((data) => { this.title += data["abilityResult"]; // 此处取到运算结果,并加到title之后 }); } }
为了方便结果展示,这里对同目录下的index.hml也做一点修改,让页面中只显示title的内容。
<div class="container"> <text class="title"> {{ title }} </text> </div>
结果验证
启动手机模拟器,启动成功后运行应用,看到如下显示则说明js2java-codegen工具生成了有效的模板代码,成功地建立起了FA调用PA的通道。
模拟器验证效果