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

开发
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

[[384266]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

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

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

1、新建一个Service Ability

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

在自动生成的众多重载方法中,我们需要用到的是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; 
        } 
    } 
 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

主要需实现的两个方法是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,完整逻辑代码如下:

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<String, Object> result = new HashMap<>(5); 
            if (code == LIST_COMMENTS) { 
                // 获取并转化请求数据 
                String req = data.readString(); 
                WordReq param = ZSONObject.stringToClass(req, WordReq.class); 
                List<String> 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; 
        } 
    } 
 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.

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); 
        }) 
    } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.

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

运行效果:

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

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-02-23 12:25:26

鸿蒙HarmonyOS应用开发

2021-02-20 09:52:02

鸿蒙HarmonyOS应用开发

2021-02-21 11:09:18

鸿蒙HarmonyOS应用开发

2021-02-23 12:23:57

鸿蒙HarmonyOS应用开发

2021-02-22 14:56:55

鸿蒙HarmonyOS应用开发

2021-02-25 10:01:19

鸿蒙HarmonyOS应用开发

2021-02-04 13:49:41

鸿蒙HarmonyOS应用开发

2021-02-23 09:52:42

鸿蒙HarmonyOS应用开发

2021-02-05 09:46:16

鸿蒙HarmonyOSjs开发

2021-02-25 15:13:08

鸿蒙HarmonyOS应用开发

2021-02-24 09:36:03

鸿蒙CSS应用开发

2021-02-07 09:17:24

鸿蒙HarmonyOS应用开发

2017-05-08 15:03:07

微信小程序开发实战

2016-09-27 16:38:24

JavaScript微信Web

2016-11-04 10:49:48

微信小程序

2016-09-28 18:10:59

微信程序MINA

2016-09-27 20:36:23

微信HttpWeb

2016-11-04 10:30:17

微信小程序

2018-09-11 10:32:07

云开发小程序开发者

2016-11-07 10:30:07

微信小程序安装配置
点赞
收藏

51CTO技术栈公众号