0

HarmonyOS 使用FA调PA能力实现JS消息订阅功能

 1 year ago
source link: https://blog.51cto.com/harmonyos/5366614
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

HarmonyOS 使用FA调PA能力实现JS消息订阅功能

推荐 原创

作者: 余香鑫

目前JS UI框架提供的事件发布订阅功能需要在API7版本上才能使用, 为满足开发需求, 我们在JAVA侧实现消息订阅分发逻辑, 通过JS调JAVA能力将接口暴露给JS侧, 以实现消息订阅发布能力

HarmonyOS 使用FA调PA能力实现JS消息订阅功能_FA调用PA

1. 定义消息数据

一个消息事件包含事件类型, 携带数据, 我们先定义一个JavaBean对象表示消息数据

class Event {
    private String type;
    private String data;
}

2. 定义接口

消息数据模型有了, 可以开始定义接口了.

  • 消息订阅接口,
    key用于表示订阅者对象的标识. callback是消息的回调接口, 我们希望订阅者只接收到自己关心的事件, 所以还需要增加一个参数subscribeEventTypes表示关心的事件类型

    void subscribeEvent(key, subscribeEventTypes, callback) 
    
  • 取消订阅接口
    有订阅就会有取消, key用于表示订阅者对象的唯一标识

    void unSubscribeEvent(key)
    
  • 发布消息接口
    发布消息接口, type表示消息类型, data表示携带的数据

    void publishEvent(type, data)
    

3. JAVA侧逻辑

我们采用的是是PA调FA机制, 所以需要新建一个JAVA远程服务Ability, 目前有ServerInternal两种类型的服务Ability, 此处不需要考虑多进程和 生命周期问题, 所以这里使用InternalAbility.

3.1 先创建一个类EventInternalAbility, 调用setInternalAbilityHandler接口实现JS侧请求处理接口, 处理三种请求

public class EventInternalAbility extends AceInternalAbility {
    private final ConcurrentHashMap<String, EventObserver> observers = new ConcurrentHashMap<>(10);

    private EventInternalAbility() {
        setInternalAbilityHandler(this::onRemoteRequest);
    }

    private boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
        switch (code) {
            case SUBSCRIBE: // 处理订阅消息请求
                addObserver();
                break;
            case UNSUBSCRIBE: // 处理取消订阅消息请求
                removeObserver();
                break;
            case PUBLISH_EVENT: // 处理消息分发
                publishEvent();
                break;
        }
        return true;
    }
}

3.2 处理订阅消息请求, 我们需要在此函数下处理消息订阅的事件类型和订阅对象

public class EventInternalAbility {
    private void addObserver(MessageParcel data) {
        JSON dataJson = new JSON(data.readString());
        // 解析订阅者的标识
        String key = dataJson.get("key");
        // 解析订阅者关系的数据
        List<String> subscribeEventTypes = dataJson.get("subscribeEventType");
        // 添加订阅者到map队列中
        observers.put(key, new EventObserver(subscribeEventTypes, data.readRemoteObject()));
    }
}

3.3 处理取消订阅消息请求, 此逻辑比较简单, 将标识对应的订阅对象移除即可

    observers.remove(key)

3.4 处理消息分发请求, 我们需要在此函数下完成消息数据解析和消息分发处理

public class EventInternalAbility {
    private void publishEvent(MessageParcel data) {
        // 解析数据
        JSON dataJson = new JSON(data.readString());
        Stirng eventType = dataJson.get("type");
        Stirng eventData = dataJson.get("data");
        // 分发消息
        observers.forEach((key, eventObserver) -> {
            if (eventObserver.getSubscribeEventType().contains(eventType)) {
                eventObserver.handlenEvent(eventType, eventData);
            }
        });
    }
}

3.5 到此我们JAVA侧的关键代码已经完成, 我们还需要在应用启动入口添加启动EventInternalAbility服务

public class EventInternalAbility {
    private static final EventInternalAbility INSTANCE = new EventInternalAbility();

    // 添加启动服务分发
    public static void startServer() {
        // 我们与已经在构造函数下实现了JS侧请求处理接口, 此处可为空
    }
}

public class MyApplication extends AbilityPackage {
    @Override
    public void onInitialize() {
        super.onInitialize();
        // 在APP入口启动服务
        EventInternalAbility.startServer();
    }
}

4. JS侧逻辑

新建event-utils.js脚本文件, 实现上述定义的接口;

JS侧的代码比较简单, 主要将入参的数据透传给JAVA侧, 逻辑比较简单, 此处不再一一讲解

  • 将请求bundleName abilityName等参数抽为一个方法, 以减少重复代码
const getParams = function (code) {
    return {
        messageCode: code,
        // todo 此处修改为你项目的bundleName和abilityName
        bundleName: 'com.chinasoftinc.event',
        abilityName: 'com.chinasoftinc.event.event.EventInternalAbility',
        abilityType: 1,
        syncOption: 0,
        data: code,
    };
};
 subscribeEvent(key, subscribeEventTypes, eventCallback) {
    let subInfoParams = getParams(Constants.SUBSCRIBE_INFO);
    subInfoParams.data = {
        "key": key,
        "subscribeEventTypes": subscribeEventTypes,
    }            
    FeatureAbility.subscribeAbilityEvent(params, eventCallback)
 }
   unsubscribeEvent(key){
      let params = getParams(Constants.UNSUBSCRIBE);
      params.data = {
        "key": key
      }
      FeatureAbility.unsubscribeAbilityEvent(params)
   }
   publishEvent(type, data){
      let params = getParams(Constants.PUBLISH_EVENT);
      params.data = {
        "type": type,
        "data": data,
      }
      return  FeatureAbility.callAbility(params)   
   }
HarmonyOS 使用FA调PA能力实现JS消息订阅功能_js消息订阅功能_02

至此关键代码逻辑已全部完成, 总体来说流程比较简单, 主要使用JS UI框架提供的FA调PA能力, 将JAVA侧的操作能力提供给JS侧使用.
 完整项目代码可以前往Gitee查看

更多原创内容请关注: 中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

 想了解更多关于开源的内容,请访问:

 51CTO 开源基础软件社区

 https://ost.51cto.com/#bkwz

  • 打赏
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK