【FFH】JSFA调用PA(二) Internal Ability调用方式 原创 精华

Hagon
发布于 2022-2-12 22:22
浏览
3收藏

春节不停更,此文正在参加「星光计划-春节更帖活动」

JS FA调用Java PA(二)Internal Ability调用方式

引言

上一篇文章我们已经了解到了Ability的概念,还有JS FA调用Java PA两种方式,Ability和Internal Ability的区别。

​ 因为刚开始学习,一般是使用Internal Ability比较多,所以我们借助具体参照官方Gitee仓库的示例来一起学习一下Internal Ability的具体调用方法。

JS FA调用Java PA — InternalAbility调用方式

JS FA端(Internal Ability)

FA端相对PA端比较简单,官方提供的API也只有三个:

怎么理解这三个的区别呢?其实很简单,假设我们现在要做一个获取手机电池情况的应用,它具备三个功能分别对应的API如下:

  • 获取手机电量———调用PA能力
  • 监听手机电量变化(电量变化就给用户发送通知)———订阅PA能力———订阅PA能力
  • 取消监听手机电量变化———取消订阅PA能力

这样相信大家大概能理解这几个接口的区别了。

另外提一下,这几个API支持大部分富设备。

注:这三个接口的返回值均为Promise类型,格式为JSON字符串

【FFH】JSFA调用PA(二) Internal Ability调用方式-鸿蒙开发者社区【FFH】JSFA调用PA(二) Internal Ability调用方式-鸿蒙开发者社区

1.参数初始化

首先我们来看一下参数,虽然官方文档把这三个API的接口参数分成了三部分描述,但是其实参数都一样,唯一区别就是,FeatureAbility.callAbility的有Data这个请求参数

  • bundleName:Ability的包名称,需要与PA端匹配,区分大小写。
  • abilityName:Ability名称,需要与PA端匹配,区分大小写。
  • messageCode:Ability操作码(操作码定义PA的业务功能,需要与PA端约定),可以自己设置,不同的码对应着要处理的不同业务。
  • abilityType:Ability类型,对应PA端不同的实现方式:
    • 0:Ability调用方式
    • 1:Internal Ability调用方式
  • data:发送到Ability的数据(根据不同的业务携带相应的业务数据,数据字段名称需要与PA端约定),只有FeatureAbility.callAbility接口有。
  • syncOption:PA侧请求消息处理同步/异步选项,非必填,默认使用同步方式。当前异步方式仅支持AbilityType为Internal Ability类型
    • 0:同步方式,默认方式
    • 1:异步方式。

既然参数都一样,那为什么不统一封装起来,提高代码复用性呢,那第一步是先要封装一个参数初始化函数:

我们在自己的js页面中,先创建一个action对象,初始化好后进行返回。

【FFH】JSFA调用PA(二) Internal Ability调用方式-鸿蒙开发者社区【FFH】JSFA调用PA(二) Internal Ability调用方式-鸿蒙开发者社区

initAction: function (code) {
    var actionData = {};
    var action = {};
    action.bundleName = "ohos.samples.jscalljava";
    action.abilityName = "BatteryInternalAbility";
    action.messageCode = code;
    action.data = actionData;
    action.abilityType = 1;
    action.syncOption = 0;
    return action;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

2.FeatureAbility.callAbility(OBJECT)

​ 我们知道了获取手机电量这个功能是基于调用PA能力,下面我们来来看看怎么实现该部分代码

    getBatteryLevel: async function () {
        try {
            var action = this.initAction(1001);  //给封装好的初始化函数传递操作码,确定要调用的业务
            var result = await FeatureAbility.callAbility(action); //调用API
            console.info(" result = " + result);
            this.showToast(result);      //在界面上弹出结果
        } catch (pluginError) {
            console.error("getBatteryLevel : Plugin Error = " + pluginError);
        }
    },
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

3.FeatureAbility.subscribeAbilityEvent(OBJECT)

​ 接着是监听手机电量变化:

    batteryLevelSubscribe: async function () {
        try {
            var action = this.initAction(1002); //给封装好的初始化函数传递操作码,确定要调用的业务
            var that = this;
            var result = await FeatureAbility.subscribeAbilityEvent(action,function (batteryLevel) { //调用订阅服务API
                console.info(" batteryLevel info is: " + batteryLevel);
                var batteryData = JSON.parse(batteryLevel).data;  //将Json字符串转换为对象,并获取接口返回数据
                that.showToast(" batteryState change: " + batteryData.msg);
            });
            this.showToast(" subscribe result " + result);
            console.info(" subscribeCommonEvent result = " + result);
        } catch (pluginError) {
            console.error("subscribeCommonEvent error : result= " + result + JSON.stringify(pluginError));
        }
    },
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

4.FeatureAbility.unsubscribeAbilityEvent(OBJECT)

​ 最后是取消订阅:

    batteryLevelUnSubscribe: async function () {
        try {
            var action = this.initAction(1003);
            var result = await FeatureAbility.unsubscribeAbilityEvent(action);
            FeatureAbility.callAbility(action);
            this.showToast("unsubscribe result " + result);
        } catch (pluginError) {
            console.error("batteryLevelUnSubscribe error : " + JSON.stringify(pluginError));
            this.showToast("batteryLevelUnSubscribe error : " + JSON.stringify(pluginError));
        }
    },
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

完整示例

具体参照官方Gitee仓库的示例

https://gitee.com/harmonyos/harmonyos_app_samples/tree/master/JSUI/JsCallJava

import prompt from '@system.prompt'

export default {
    batteryLevel: function () {
        this.getBatteryLevel();
    },
    batterySubscribe: function () {
        this.batteryLevelSubscribe();
    },
    batteryUnSubscribe: function () {
        this.batteryLevelUnSubscribe();
    },
    initAction: function (code) {
        var actionData = {};
        var action = {};
        action.bundleName = "ohos.samples.jscalljava";
        action.abilityName = "BatteryInternalAbility";
        action.messageCode = code;
        action.data = actionData;
        action.abilityType = 1;
        action.syncOption = 0;
        return action;
    },
    getBatteryLevel: async function () {
        try {
            var action = this.initAction(1001);  //给封装好的初始化函数传递操作码,确定要调用的业务
            var result = await FeatureAbility.callAbility(action); //调用API
            console.info(" result = " + result);
            this.showToast(result);      //在界面上弹出结果
        } catch (pluginError) {
            console.error("getBatteryLevel : Plugin Error = " + pluginError);
        }
    },
    batteryLevelSubscribe: async function () {
        try {
            var action = this.initAction(1002); //给封装好的初始化函数传递操作码,确定要调用的业务
            var that = this;
            var result = await FeatureAbility.subscribeAbilityEvent(action,function (batteryLevel) { //调用订阅服务API
                console.info(" batteryLevel info is: " + batteryLevel);
                var batteryData = JSON.parse(batteryLevel).data;  //将Json字符串转换为对象,并获取接口返回数据
                that.showToast(" batteryState change: " + batteryData.msg);
            });
            this.showToast(" subscribe result " + result);
            console.info(" subscribeCommonEvent result = " + result);
        } catch (pluginError) {
            console.error("subscribeCommonEvent error : result= " + result + JSON.stringify(pluginError));
        }
    },
    batteryLevelUnSubscribe: async function () {
        try {
            var action = this.initAction(1003);
            var result = await FeatureAbility.unsubscribeAbilityEvent(action);
            FeatureAbility.callAbility(action);
            this.showToast("unsubscribe result " + result);
        } catch (pluginError) {
            console.error("batteryLevelUnSubscribe error : " + JSON.stringify(pluginError));
            this.showToast("batteryLevelUnSubscribe error : " + JSON.stringify(pluginError));
        }
    },
    showToast: function (msg) {
        prompt.showToast({
            message: msg
        });
    }
}

  • 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.
  • 65.
  • 66.

Java PA端(Internal Ability)

1.导入ohos相关接口包

在java目录下新建一个Ability文件

package ohos.samples.jscalljava;

import ohos.ace.ability.AceInternalAbility;
import ohos.batterymanager.BatteryInfo;
import ohos.event.commonevent.CommonEventData;
import ohos.event.commonevent.CommonEventManager;
import ohos.event.commonevent.CommonEventSubscribeInfo;
import ohos.event.commonevent.CommonEventSubscriber;
import ohos.event.commonevent.CommonEventSupport;
import ohos.event.commonevent.MatchingSkills;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;


  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

2.创建一个继承Ability的类

public class BatteryInternalAbility extends AceInternalAbility {
    private static final int BATTERY_LEVEL_NOT_AVAILABLE = 1001; // 与FA协商好的Ability操作码,对应不同业务功能

    private static final int BATTERY_SUBSCRIBE_FAILURE = 1002;   // 与FA协商好的Ability操作码,对应不同业务功能

    private static final int BATTERY_UNSUBSCRIBE_FAILURE = 1003; // 与FA协商好的Ability操作码,对应不同业务功能

    private static final String TAG = BatteryInternalAbility.class.getSimpleName();

    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);// 定义日志标签

    private static final int DEFAULT_TYPE = 0;

    private static BatteryInternalAbility instance;

    private static final String BUNDLE_NAME = "ohos.samples.jscalljava";

    private static final String ABILITY_NAME = "BatteryInternalAbility";

    private CommonEventSubscriber subscriber;
// 如果多个Ability实例都需要注册当前InternalAbility实例,需要更改构造函数,设定自己的bundleName和abilityName
    private BatteryInternalAbility() { 
        super(BUNDLE_NAME, ABILITY_NAME);
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

3.封装业务逻辑调用

public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
        switch (code) {
            case BATTERY_LEVEL_NOT_AVAILABLE:
                reply.writeString(getBatteryInfo());
                break;
            case BATTERY_SUBSCRIBE_FAILURE:
                subscribeEvent(data, reply, option);
                break;
            case BATTERY_UNSUBSCRIBE_FAILURE:
                unSubscribeBatteryEvent(reply);
                break;
            default:
                reply.writeString("service not defined");
                return false;
        }
        return true;
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

4.调用onRemoteRequest接口与FA完成交互逻辑

【FFH】JSFA调用PA(二) Internal Ability调用方式-鸿蒙开发者社区【FFH】JSFA调用PA(二) Internal Ability调用方式-鸿蒙开发者社区

注:该接口返回值为布尔值,操作成功返回true,否则返回false。

    

    private void subscribeEvent(MessageParcel data, MessageParcel reply, MessageOption option) {
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_BATTERY_CHANGED);
        IRemoteObject notifier = data.readRemoteObject();
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        subscriber = new CommonEventSubscriber(subscribeInfo) {
            @Override
            public void onReceiveEvent(CommonEventData commonEventData) {
                replyMsg(notifier);
            }
        };
        if (option.getFlags() == MessageOption.TF_SYNC) {
            reply.writeString("subscribe common event success");
        }
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
            reply.writeString(" subscribe common event success");
        } catch (RemoteException e) {
            HiLog.info(LABEL_LOG, "%{public}s", "RemoteException in subscribeNotificationEvents!");
        }
    }

    private void replyMsg(IRemoteObject notifier) {
        MessageParcel notifyData = MessageParcel.obtain();
        notifyData.writeString("{\"msg\":\"" + getBatteryInfo() + "\"}");
        try {
            notifier.sendRequest(DEFAULT_TYPE, notifyData, MessageParcel.obtain(), new MessageOption());
        } catch (RemoteException exception) {
            HiLog.info(LABEL_LOG, "%{public}s", "replyMsg RemoteException !");
        } finally {
            notifyData.reclaim();
        }
    }

    private String getBatteryInfo() {
        StringBuilder stringBuilder = new StringBuilder();
        boolean isCharging = getChargingStatus();
        double batteryValue = getBatteryLevel();
        stringBuilder.append(batteryValue).append(" % Battery Left").append(System.lineSeparator())
            .append("isCharging: ")
            .append(isCharging);
        return stringBuilder.toString();
    }

    private void unSubscribeBatteryEvent(MessageParcel reply) {
        try {
            CommonEventManager.unsubscribeCommonEvent(subscriber);
            reply.writeString("Unsubscribe common event success!");
        } catch (RemoteException | IllegalArgumentException exception) {
            reply.writeString("Battery Unsubscribe failed!");
            HiLog.info(LABEL_LOG, "%{public}s", "Battery Unsubscribe failed!");
        }
        subscriber = null;
    }

    private int getBatteryLevel() {
        BatteryInfo batteryInfo = new BatteryInfo();
        return batteryInfo.getCapacity();
    }

    private boolean getChargingStatus() {
        BatteryInfo batteryInfo = new BatteryInfo();
        BatteryInfo.BatteryChargeState batteryStatus = batteryInfo.getChargingStatus();
        return (batteryStatus == BatteryInfo.BatteryChargeState.ENABLE
            || batteryStatus == BatteryInfo.BatteryChargeState.FULL);
    }

    /**
     * BatteryInternalAbility
     *
     * @return If the instance is NULL, Get new instance. Otherwise, instance is returned.
     */
    public static BatteryInternalAbility getInstance() {
        if (instance == null) {
            synchronized (BatteryInternalAbility.class) {
                if (instance == null) {
                    instance = new BatteryInternalAbility();
                }
            }
        }
        return instance;
    }
  • 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.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.

5.注册和注销InternalAbility

    /**
     * Internal ability 注册接口
     */
    public void register() {
        this.setInternalAbilityHandler(this::onRemoteRequest);
    }

    /**
     * Internal ability 注销接口
     */
    public void deregister() {
        this.setInternalAbilityHandler(null);
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

完整示例

具体参照官方Gitee仓库的示例

https://gitee.com/harmonyos/harmonyos_app_samples/tree/master/JSUI/JsCallJava

package ohos.samples.jscalljava;

import ohos.ace.ability.AceInternalAbility;
import ohos.batterymanager.BatteryInfo;
import ohos.event.commonevent.CommonEventData;
import ohos.event.commonevent.CommonEventManager;
import ohos.event.commonevent.CommonEventSubscribeInfo;
import ohos.event.commonevent.CommonEventSubscriber;
import ohos.event.commonevent.CommonEventSupport;
import ohos.event.commonevent.MatchingSkills;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;

/**
 * Internal Ability
 */
public class BatteryInternalAbility extends AceInternalAbility {
    private static final int BATTERY_LEVEL_NOT_AVAILABLE = 1001; // 与FA协商好的Ability操作码,对应不同业务功能

    private static final int BATTERY_SUBSCRIBE_FAILURE = 1002;   // 与FA协商好的Ability操作码,对应不同业务功能

    private static final int BATTERY_UNSUBSCRIBE_FAILURE = 1003; // 与FA协商好的Ability操作码,对应不同业务功能

    private static final String TAG = BatteryInternalAbility.class.getSimpleName();

    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);// 定义日志标签

    private static final int DEFAULT_TYPE = 0;

    private static BatteryInternalAbility instance;

    private static final String BUNDLE_NAME = "ohos.samples.jscalljava";

    private static final String ABILITY_NAME = "BatteryInternalAbility";

    private CommonEventSubscriber subscriber;

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


    public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
        switch (code) {
            case BATTERY_LEVEL_NOT_AVAILABLE:
                reply.writeString(getBatteryInfo());
                break;
            case BATTERY_SUBSCRIBE_FAILURE:
                subscribeEvent(data, reply, option);
                break;
            case BATTERY_UNSUBSCRIBE_FAILURE:
                unSubscribeBatteryEvent(reply);
                break;
            default:
                reply.writeString("service not defined");
                return false;
        }
        return true;
    }

    private void subscribeEvent(MessageParcel data, MessageParcel reply, MessageOption option) {
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_BATTERY_CHANGED);
        IRemoteObject notifier = data.readRemoteObject();
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        subscriber = new CommonEventSubscriber(subscribeInfo) {
            @Override
            public void onReceiveEvent(CommonEventData commonEventData) {
                replyMsg(notifier);
            }
        };
        if (option.getFlags() == MessageOption.TF_SYNC) {
            reply.writeString("subscribe common event success");
        }
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
            reply.writeString(" subscribe common event success");
        } catch (RemoteException e) {
            HiLog.info(LABEL_LOG, "%{public}s", "RemoteException in subscribeNotificationEvents!");
        }
    }

    private void replyMsg(IRemoteObject notifier) {
        MessageParcel notifyData = MessageParcel.obtain();
        notifyData.writeString("{\"msg\":\"" + getBatteryInfo() + "\"}");
        try {
            notifier.sendRequest(DEFAULT_TYPE, notifyData, MessageParcel.obtain(), new MessageOption());
        } catch (RemoteException exception) {
            HiLog.info(LABEL_LOG, "%{public}s", "replyMsg RemoteException !");
        } finally {
            notifyData.reclaim();
        }
    }

    private String getBatteryInfo() {
        StringBuilder stringBuilder = new StringBuilder();
        boolean isCharging = getChargingStatus();
        double batteryValue = getBatteryLevel();
        stringBuilder.append(batteryValue).append(" % Battery Left").append(System.lineSeparator())
            .append("isCharging: ")
            .append(isCharging);
        return stringBuilder.toString();
    }

    private void unSubscribeBatteryEvent(MessageParcel reply) {
        try {
            CommonEventManager.unsubscribeCommonEvent(subscriber);
            reply.writeString("Unsubscribe common event success!");
        } catch (RemoteException | IllegalArgumentException exception) {
            reply.writeString("Battery Unsubscribe failed!");
            HiLog.info(LABEL_LOG, "%{public}s", "Battery Unsubscribe failed!");
        }
        subscriber = null;
    }

    private int getBatteryLevel() {
        BatteryInfo batteryInfo = new BatteryInfo();
        return batteryInfo.getCapacity();
    }

    private boolean getChargingStatus() {
        BatteryInfo batteryInfo = new BatteryInfo();
        BatteryInfo.BatteryChargeState batteryStatus = batteryInfo.getChargingStatus();
        return (batteryStatus == BatteryInfo.BatteryChargeState.ENABLE
            || batteryStatus == BatteryInfo.BatteryChargeState.FULL);
    }

    /**
     * BatteryInternalAbility
     *
     * @return If the instance is NULL, Get new instance. Otherwise, instance is returned.
     */
    public static BatteryInternalAbility getInstance() {
        if (instance == null) {
            synchronized (BatteryInternalAbility.class) {
                if (instance == null) {
                    instance = new BatteryInternalAbility();
                }
            }
        }
        return instance;
    }

    /**
     * Internal ability 注册接口
     */
    public void register() {
        this.setInternalAbilityHandler(this::onRemoteRequest);
    }

    /**
     * Internal ability 注销接口
     */
    public void deregister() {
        this.setInternalAbilityHandler(null);
    }
}

  • 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.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.

代码参考

具体参照官方Gitee仓库的示例
https://gitee.com/harmonyos/harmonyos_app_samples/tree/master/JSUI/JsCallJava
方便大家取到代码,已将源码压缩文件添加至附件

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
JsCallJava.zip 91.44K 13次下载
已于2022-2-14 13:40:23修改
4
收藏 3
回复
举报
4
2
3
2条回复
按时间正序
/
按时间倒序
Hagon
Hagon
Hagon
回复
2022-2-14 13:45:02
回复
    相关推荐
    这个用户很懒,还没有个人简介
    帖子
    视频
    声望
    粉丝
    社区精华内容