#2020征文-手机#浅谈JS与Java在手机APP中的混合开发方式 原创 精华

执剑天涯奈我何
发布于 2021-1-24 00:15
浏览
46收藏

         在进行鸿蒙应用开发中由于每个人的开发习惯不同,鸿蒙官方文档说明中也是支持多种开发方式,今天跟大家聊聊关于JS跟Java之间混合开发方式。

 

基本介绍

        首先是因为我个人习惯使用JS进行页面开发布局,但是鸿蒙提供的Java API的功能比JS API的功能要强大,所以我选择用JS开发页面用Java实现逻辑交互,那么这两者之间如何进行通信就是我们需要考虑的问题。好在官方文档中有关于JS API调用Java API 机制的说明,FA提供了三个JS接口分别为:

  1. FeatureAbility.callAbility(OBJECT):调用PA能力;
  2. FeatureAbility.subscribeAbilityEvent(OBJECT, Function):订阅PA能力;
  3. FeatureAbility.unsubscribeAbilityEvent(OBJECT):取消订阅PA能力。

        在PA端也有对应的接口其包含远端调用Ability和本地调用Internal Ability两种方式。

        PA端调用Ability接口方式为:boolean IRemoteObject.onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option);

        PA端调用Internal Ability 接口方式为:boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option)

       JS端与Java通过接口扩展机制进行通信,通过bundleName和abilityName进行关联,所以我们要建立两者之间的通信,根据提供的接口字段进行相对应匹配。

        接下来通过我写的例子方便大家更好的去理解JS是如何调用PA能力的。

 

权限配置

本示例需要位置权限,因此在config.json中添加以下字段,还有就是需要在手机中打开定位开关

"reqPermissions": [  {  "name": "ohos.permission.LOCATION"  }],

 

代码演示

JS端接口代码如下:其中messageCode、abilityType、syncOption值根据文档进行配置 

aa:async function (){
               var actionData = {};
               actionData.longitude = this.longitude;
               actionData.latitude = this.latitude;
                var action = {};
                action.data = actionData;
                action.bundleName = 'com.example.shundaschool';
                action.abilityName = 'com.example.shundaschool.LocationAbility';
                action.messageCode = 666;
                action.abilityType = 1;
                action.syncOption = 1;
                var result = await FeatureAbility.callAbility(action);
                var ret = JSON.parse(result);
                console.info("00000" + ret);
                console.info("0022" + JSON.stringify(ret.abilityResult));
                this.$set("address",JSON.stringify(ret.abilityResult))
    },

PA端接口代码如下:

... ...

private static final String BUNDLE_NAME = "com.example.shundaschool";
private static final String ABILITY_NAME = "com.example.shundaschool.LocationAbility";

... ...

public LocationAbility() {
    super(BUNDLE_NAME, ABILITY_NAME);
}

    public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
        switch (code) {
                case location: {
                String zsonStr = data.readString();
                RequestParamsss param = ZSONObject.stringToClass(zsonStr, RequestParamsss.class);
                System.out.println("我是param经度:"+param.getLatitude());
                System.out.println("我是param纬度:"+param.getLongitude());
                // 返回结果当前仅支持String,对于复杂结构可以序列化为ZSON字符串上报
                GeoConvert geoConvert = new GeoConvert();
                try{
                    List<GeoAddress> address = geoConvert.getAddressFromLocation(param.getLatitude(), param.getLongitude(), 1);
//                    System.out.println(address);
//                    System.out.println(address.get(0).getDescriptions(0));
                    Map<String, Object> zsonResult = new HashMap<String, Object>();
                    zsonResult.put("code", SUCCESS);
                System.out.println("我是param:" +  param);
                    zsonResult.put("abilityResult",  address.get(0).getDescriptions(0));
                    if (option.getFlags() == MessageOption.TF_SYNC) {
                        reply.writeString(ZSONObject.toZSONString(zsonResult));
                    } else {
                        // ASYNC
                        MessageParcel reponseData = MessageParcel.obtain();
                        reponseData.writeString(ZSONObject.toZSONString(zsonResult));
                        IRemoteObject remoteReply = reply.readRemoteObject();
                        try {
                            remoteReply.sendRequest(0, reponseData, MessageParcel.obtain(), new MessageOption());
                            reponseData.reclaim();
                        } catch (RemoteException exception) {
                            return false;
                        }
                    }
                }catch (IOException e){
                    System.out.println("获取位置信息异常");
                }
                break;
            }
            default:{
                reply.writeString("service not defined");
               
            }
        }
        return true;
    }  

实现效果图展示如下:

点击获取位置信息展示设备经纬度,再次点击查看位置通过逆地址转换展示具体位置#2020征文-手机#浅谈JS与Java在手机APP中的混合开发方式-鸿蒙开发者社区#2020征文-手机#浅谈JS与Java在手机APP中的混合开发方式-鸿蒙开发者社区

这两者能够正常进行通信后,这样我们就能够在JS UI中进行页面布局,在Java UI里进行逻辑处理了,希望以上内容能对大家有所帮助。

   

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-1-26 11:48:16修改
46
收藏 46
回复
举报
17条回复
按时间正序
/
按时间倒序
wx600c53a272b37
wx600c53a272b37

大佬带带我

回复
2021-1-24 00:50:00
纸上得来终觉浅_绝知此事要躬行
纸上得来终觉浅_绝知此事要躬行

666666666

回复
2021-1-24 01:15:37
Jack__Pan?
Jack__Pan?

思路清晰,希望多出好文章。

回复
2021-1-24 09:20:12
mb600ced76427c6
mb600ced76427c6

真棒,兄弟,必须支持😄

回复
2021-1-24 11:46:33
执剑天涯奈我何
执剑天涯奈我何 回复了 Jack__Pan?
思路清晰,希望多出好文章。

会的会的,有问题可以随时交流

回复
2021-1-24 13:55:09
执剑天涯奈我何
执剑天涯奈我何 回复了 wx600c53a272b37
大佬带带我

一起学习

回复
2021-1-24 13:55:54
wx5c05083195ab4
wx5c05083195ab4

写的很好,痘痘都没了

1
回复
2021-1-24 14:40:24
zk0301
zk0301

折腾。。。

回复
2021-1-29 09:26:14
鸿蒙张荣超
鸿蒙张荣超

最好能把源代码打个包作为附件^_^

回复
2021-1-29 20:23:45
wx601cb5b0b658d
wx601cb5b0b658d

老哥,你js+java调试时, 有没有遇到debug port busy

回复
2021-2-22 17:10:58
mb6021fd77767fa
mb6021fd77767fa

两个省略号 省略的是啥

回复
2021-2-23 15:44:17
执剑天涯奈我何
执剑天涯奈我何 回复了 mb6021fd77767fa
两个省略号 省略的是啥

包的引入与常量定义,省略这些官网例子里边都有

回复
2021-2-24 16:30:10
执剑天涯奈我何
执剑天涯奈我何 回复了 wx601cb5b0b658d
老哥,你js+java调试时, 有没有遇到debug port busy

没有遇到呢

回复
2021-2-24 16:30:52
执剑天涯奈我何
执剑天涯奈我何 回复了 mb6021fd77767fa
两个省略号 省略的是啥


import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.ace.ability.AceInternalAbility;
import ohos.app.AbilityContext;
import ohos.location.GeoAddress;
import ohos.location.GeoConvert;

import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;
import ohos.utils.zson.ZSONObject;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LocationAbility extends AceInternalAbility {
    private static final String TAG = LocationAbility.class.getSimpleName();
    private static final String BUNDLE_NAME = "com.example.shundaschool";
    private static final String ABILITY_NAME = "com.example.shundaschool.LocationAbility";
    private static final int ERROR = -1;
    private static final int SUCCESS = 0;
    private static final int location = 666;
    private static LocationAbility instance;
    private AbilityContext abilityContext;

    // 如果多个Ability实例都需要注册当前InternalAbility实例,需要更改构造函数,设定自己的bundleName和abilityName
    public LocationAbility() {
        super(BUNDLE_NAME, ABILITY_NAME);
    }

.......后边的文章里都有了

回复
2021-2-24 16:33:42
mb6021fd77767fa
mb6021fd77767fa

java如何主动与js交互

回复
2021-4-2 09:55:54
执剑天涯奈我何
执剑天涯奈我何

目前还不清楚Java如何主动与js交互

回复
2021-4-18 09:03:34
wx57df93e6992f8
wx57df93e6992f8

RequestParamsss.class  呢  , 没有得到坐标

回复
2021-10-14 17:56:15
回复
    相关推荐