除了轻薄的智能穿戴设备外,鸿蒙目前支持的手机、汽车、电视、手表、平板电脑等都属于富鸿蒙。 JS语言项目中也有Java模块,它提供了JS跨语言调用Java方法的技术。
现在需要实现查看商品评论时长评论、中评论、短评论的比例统计。 这里请求评论数据,调用Java进行估算。
JS 调用 Java 有两种方式:Ability 和InternalAbility。 前者可以被不同的JS方法调用,后者适合与JS业务逻辑强相关、信噪比要求高的服务。 这里使用了能力的形式。
01
打造新服务能力
在项目工程目录的Java模块中,右键单击该项目的包调用javascript方法,新建→能力→清空服务能力。
在手动生成的众多重载方法中,我们需要使用的是onConnect()。 该方法在第一次连接时反弹,返回一个IRemoteObject对象,用于后续的业务通信。
因此创建一个继承RemoteObject类并实现IRemoteBroker接口的内部类。
代码框架如下:
public class ServiceAbility extends Ability {
private MyRemote remote = new MyRemote();
@Override
public IRemoteObject onConnect(Intent intent) {
super.onConnect(intent);
return remote.asObject();
}
static class MyRemote extends RemoteObject implements IRemoteBroker {
MyRemote() {
super("MyService_MyRemote");
}
MyRemote(String descriptor) {
super(descriptor);
}
@Override
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
......
}
@Override
public IRemoteObject asObject() {
return this;
}
}
}
主要要实现的两个方法是onRemoteRequest()和asObject()。
在onConnect()方法中返回内部类的例子中,asObject()直接返回this。
onRemoteRequest()是需要实现的主要业务方法,有四个参数:
02
完善的代码逻辑
规定JS端每次加载页面中的评论数据时,都会将当前页面中的所有评论内容发送到Java端进行估算。 这个过程有点类似于HTTP,获取数据、处理数据、返回数据。
鸿蒙提供了ZSONObject来处理json。 完整逻辑代码如下:
public class ServiceAbility extends Ability {
private MyRemote remote = new MyRemote();
@Override
public IRemoteObject onConnect(Intent intent) {
super.onConnect(intent);
return remote.asObject();
}
static class MyRemote extends RemoteObject implements IRemoteBroker {
private static final int LIST_COMMENTS = 200;
private static final int SUCCESS = 0;
private static final int ERROR = 500;
MyRemote() {
super("MyService_MyRemote");
}
MyRemote(String descriptor) {
super(descriptor);
}
@Override
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
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());
// 统计评论字数
int longComments = (int) comments.stream().mapToInt(String::length).filter(len -> len >= 200).count();
int mediumComments = (int) comments.stream().mapToInt(String::length).filter(len -> len >= 30 && len < 200).count();
int shortComments = (int) comments.stream().mapToInt(String::length).filter(len -> len < 30).count();
// 计算占比
DecimalFormat df = new DecimalFormat("#.00");
double longPer = 1.0 * longComments / comments.size() * 100;
double mediumPer = 1.0 * mediumComments / comments.size() * 100;
double shortPer = 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));
return true;
} else {
result.put("code", ERROR);
result.put("msg", "invalid code");
reply.writeString(ZSONObject.toZSONString(result));
return false;
}
}
@Override
public IRemoteObject asObject() {
return this;
}
}
}
03
JS端远程调用
Java服务部分已经写好了。 在JS中,鸿蒙为Java服务的单次请求提供了FeatureAbility.callAbility()方法。
其参数如下:
本例中,方法如下:
// 调用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中定义的一致。
跑步疗效:
但加入Java部分后调用javascript方法,项目编译速度明显变慢。 接下来的两步就花了很长时间。 有谁知道有什么办法可以加快速度吗?
发表评论