ajax调用java程序,从微信小程序到鸿蒙JS开发-JS调用Java

1a7db37525f12a48238d7c58f66554f0.png

除轻量级智能穿戴设备,现鸿蒙支持的手机、汽车、TV、手表、平板等属于富鸿蒙,在JS语言的项目中也有Java模块,并提供了JS跨语言调用Java方法的技术。现需要实现查看商品评论时,统计出长评、中评和短评的比例,这里将评论数据请求来后调用Java进行计算。

JS调用Java有Ability方式和Internal Ability方式两种,前者可以被不同的JS方法调用,后者适用于与JS业务逻辑关联性强,响应时延要求高的服务。这里采用Ability的方式。

1、新建一个Service Ability

在项目工程目录Java模块中,右键项目的包,New->Ability->Empty Service Ability。

8b3cf0e42d80d28ff133500c06b90845.png

在自动生成的众多重载方法中,我们需要用到的是onConnect()。此方法在首次连接时回调,并返回IRemoteObject对象,用于后续的业务通信。

因此创建一个内部类,继承RemoteObject类并实现IRemoteBroker接口。代码框架如下:

publicclass ServiceAbility extends Ability {

private MyRemote remote = new MyRemote();

@Override

publicIRemoteObject onConnect(Intent intent) {

super.onConnect(intent);

returnremote.asObject();

}

staticclass MyRemote extends RemoteObject implements IRemoteBroker {

MyRemote() {

super("MyService_MyRemote");

}

MyRemote(String descriptor) {

super(descriptor);

}

@Override

publicboolean onRemoteRequest(intcode, MessageParcel data, MessageParcel reply, MessageOptionoption) {

......

}

@Override

publicIRemoteObject asObject() {

returnthis;

}

}

}

主要需实现的两个方法是onRemoteRequest()和asObject()。在onConnect()方法中返回内部类的示例,asObject()直接返回this即可。onRemoteRequest()是主要需要实现的业务方法,有四个参数:

code:JS端请求时带来的请求码,可根据code进行不同的业务处理。

data:JS端请求时带来的数据,目前仅支持json格式。Java端通过data.readString()获取请求json字符串。

reply:Java端返回给JS端的数据,目前仅支持String格式,通过reply.writeString(str)写入返回数据。

option:JS端指定同步或异步方式,Java端通过option.getFlag()获取。

2、完善代码逻辑

规定JS端每分页加载一次评论数据,就将目前页面中的所有评论内容发送给Java端进行计算。流程和HTTP有一点类似,获取数据、处理数据、返回数据。鸿蒙提供了ZSONObject可供处理json,完整逻辑代码如下:

publicclass ServiceAbility extends Ability {

private MyRemote remote = new MyRemote();

@Override

publicIRemoteObject onConnect(Intent intent) {

super.onConnect(intent);

returnremote.asObject();

}

staticclass MyRemote extends RemoteObject implements IRemoteBroker {

private staticfinalintLIST_COMMENTS = 200;

private staticfinalintSUCCESS = 0;

private staticfinalintERROR = 500;

MyRemote() {

super("MyService_MyRemote");

}

MyRemote(String descriptor) {

super(descriptor);

}

@Override

publicboolean onRemoteRequest(intcode, MessageParcel data, MessageParcel reply, MessageOptionoption) {

Map result = new HashMap<>(5);

if (code == LIST_COMMENTS) {

// 获取并转化请求数据

String req = data.readString();

WordReq param = ZSONObject.stringToClass(req, WordReq.class);

List comments = param.getList().stream().filter(e -> !"用户未填写评价内容".equals(e)).collect(Collectors.toList());

// 统计评论字数

intlongComments = (int) comments.stream().mapToInt(String::length).filter(len -> len >= 200).count();

intmediumComments = (int) comments.stream().mapToInt(String::length).filter(len -> len >= 30 && len 

intshortComments = (int) comments.stream().mapToInt(String::length).filter(len -> len 

// 计算占比

DecimalFormat df = new DecimalFormat("#.00");

doublelongPer = 1.0 * longComments / comments.size() * 100;

doublemediumPer = 1.0 * mediumComments / comments.size() * 100;

doubleshortPer = 1.0 * shortComments / comments.size() * 100;

// 返回结果

result.put("long", df.format(longPer) +"%");

result.put("medium", df.format(mediumPer) +"%");

result.put("short", df.format(shortPer) +"%");

result.put("code", SUCCESS);

result.put("msg","ok");

reply.writeString(ZSONObject.toZSONString(result));

returntrue;

} else{

result.put("code", ERROR);

result.put("msg","invalid code");

reply.writeString(ZSONObject.toZSONString(result));

returnfalse;

}

}

@Override

publicIRemoteObject asObject() {

returnthis;

}

}

}

3、JS端远程调用

Java服务部分写好了,在JS中,鸿蒙提供了FeatureAbility.callAbility()方法用于单次请求Java服务。其参数如下:

bundleName:Ability包名,在config.json中,为app.bundleName。

abilityName:调用服务端Ability类名,可省略包名,直接写".XxxAbility"。

messageCode:操作码,和Java端的"code"参数相匹配。

abilityType:Ability类型,0为Ability,1为Internal Ability。

data:请求数据,json类型。

syncOption:与Java端"option"相匹配,0为同步方式,1为异步方式。默认同步方式。

方法返回一个Promise对象,可通过.then()和.catch()处理调用成功和异常。

本例中的方法如下:

// 调用Java统计评论长度

countWords() {

let list = [];

this.comments.forEach(e => {

list.push(e.content);

})

FeatureAbility.callAbility({

bundleName: "com.example.litemall",

abilityName: ".ServiceAbility",

messageCode: 200,

abilityType: 0,

data: {

list

}

}).then(res => {

console.info(res);

let data = JSON.parse(res);

if (data.code == 0) {

this.lengths[0].value = data.long;

this.lengths[1].value = data.medium;

this.lengths[2].value = data.short;

}

}).catch(res => {

console.error(res);

})

}

Java端和JS端的代码编译完成并运行,可以看到日志中的返回数据和我们在Java中定义的一致。

52d39868f48d2ce557696139c4eaf57c.png

运行效果:

218ee3eea703595d55ca2e6f7aa51984.png

84c326367220c1b8a4f619c6e2015449.png

但加上Java的部分后,项目编译的速度明显变慢了,如下两步花了很长时间,有没有大神知道有没有什么加速的方法?

c46cd9aea9c7dc83ce85d8d73988b75d.png

1805adf15f908701cd21ef3f21c8a875.png

67eeee49b4f6094f6912c511f097e042.png

【编辑推荐】

【责任编辑:jianghua TEL:(010)68476606】

点赞 0