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

Hagon
发布于 2022-2-14 13:40
浏览
2收藏

春节不停更,此文正在参加「星光计划-春节更帖活动」
@[TOC](JS FA调用Java PA(三)Ability调用方式

引言

【FFH】JSFA调用PA(一)Ability概念及Ability与Internal Ability
【FFH】JSFA调用PA(二) Internal Ability调用方式
​ 上两篇文章我们已经了解到了Ability的概念,还有JS FA调用Java PA两种方式,Ability和Internal Ability的区别,还有第二篇文章对InternalAbility调用方式的讲解。

​ 接下来我们借助官方文档的案例来解读一下 Ability 调用方式的具体实现方法。

​ 在此之前,我们先来看一下一些相关概念。

相关概念

RPC( Remote Procedure Call)

​ Ability方式中,与FA通过RPC方式通信,先来了解一下什么是RPC,RPC 是 Remote Procedure Call ,翻译过来就是远程过程调用,说白了就是一个机器远程调用并执行另一个机器上的函数。

​ 所以他是个比较宽泛的概念,其中我们经常用到的HTTP协议就属于常见的一种RPC实现方式。

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

​ 在HarmonyOS有很多地方都用到了RPC方式通信,比如跨设备调用,远程拉起FA,FA的迁移流转等等。

Intent

​ 了解完什么是RPC,那么RPC具体是通过什么让发送方和接收机方知道要干什么的呢?其实就是接下来我们要说的对象之间传递信息的载体—Intent

​ 开发者的PA首次被FA连接时回调,并返回IRemoteObject对象,用于后续的业务通信。开发者需要继承Ability类并重写onConnect(Intent: intent)方法,其中该方法的参数就是Intent,所以他到底是拿来干嘛的呢?

​ 在HarmonyOS中提供了Intent机制来协助Ability之间的通信,例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时。

​ Intent是一个将要执行的动作的抽象的描述,在HarmonyOS中由以下元素构成:

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

​ 用大白话讲,Intent就是作为Ability之间交流的粘合剂,接收方Ability可以从Intent获得到发送方发送了什么请求。

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

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

​ 接下来进入正题。

JS FA端

​ 这部分我们就不细说,因为和InternalAbility的实现方法差不多,只是action.abilityType值不一样,要具体了解就看看上一篇文章吧。

// abilityType: 0-Ability; 1-Internal Ability
const ABILITY_TYPE_EXTERNAL = 0;
const ABILITY_TYPE_INTERNAL = 1;
// syncOption(Optional, default sync): 0-Sync; 1-Async
const ACTION_SYNC = 0;
const ACTION_ASYNC = 1;
const ACTION_MESSAGE_CODE_PLUS = 1001;
export default {
  plus: async function() {
    var actionData = {};
    actionData.firstNum = 1024;
    actionData.secondNum = 2048;

    var action = {};
    action.bundleName = 'com.example.hiaceservice';
    action.abilityName = 'com.example.hiaceservice.ComputeServiceAbility';
    action.messageCode = ACTION_MESSAGE_CODE_PLUS;
    action.data = actionData;
    action.abilityType = ABILITY_TYPE_EXTERNAL;
    action.syncOption = ACTION_SYNC;

    var result = await FeatureAbility.callAbility(action);
    var ret = JSON.parse(result);
    if (ret.code == 0) {
      console.info('plus result is:' + JSON.stringify(ret.abilityResult));
    } else {
      console.error('plus error code:' + JSON.stringify(ret.code));
    }
  }
}

PA端(Ability方式)

这里我们还是以官方文档的案例为参考,我们对官方案例进行一个步骤分解,以方便理解

https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-fa-calls-pa-examples-0000000000618000

1.导入相关ohos接口包

// ohos相关接口包
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.IRemoteBroker;
import ohos.rpc.IRemoteObject;
import ohos.rpc.RemoteObject;
import ohos.rpc.MessageParcel;
import ohos.rpc.MessageOption;
import ohos.utils.zson.ZSONObject;

import java.util.HashMap;
import java.util.Map;

2.创建一个继承Ability的类并且重写onConnect方法

​ 创建完这个类之后,先重写onConnect(Intent: intent)方法,并且在onConnect返回一个remote对象,供FA向PA发送消息。

public class ComputeServiceAbility extends Ability {
  // 定义日志标签
  private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");

  // FA在请求PA服务时会调用Ability.connectAbility连接PA,连接成功后,需要在onConnect返回一个remote对象,供FA向PA发送消息
  @Override
  protected IRemoteObject onConnect(Intent intent) {
    super.onConnect(intent);
    return remote.asObject();
  }
}

3.继承RemoteObject类重写方法完成业务逻辑

private MyRemote remote = new MyRemote();  
class MyRemote extends RemoteObject implements IRemoteBroker {
    private static final int SUCCESS = 0;
    private static final int ERROR = 1;
    private static final int PLUS = 1001;   

    MyRemote() {
      super("MyService_MyRemote");
    }
 
    @Override
    public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {
      switch (code) {
        case PLUS: {
          String dataStr = data.readString();
          RequestParam param = new RequestParam();
          try {    
              param = ZSONObject.stringToClass(dataStr, RequestParam.class);
          } catch (RuntimeException e) {    
              HiLog.error(LABEL, "convert failed.");
          }
                    
          // 返回结果当前仅支持String,对于复杂结构可以序列化为ZSON字符串上报
          Map<String, Object> result = new HashMap<String, Object>();
          result.put("code", SUCCESS);
          result.put("abilityResult", param.getFirstNum() + param.getSecondNum());
          reply.writeString(ZSONObject.toZSONString(result));
          break;
        }
        default: {
          Map<String, Object> result = new HashMap<String, Object>();
          result.put("abilityError", ERROR);
          reply.writeString(ZSONObject.toZSONString(result));
          return false;
        }
      }
      return true;   
    }
    @Override
    public IRemoteObject asObject() {
      return this;
    }
  }

完整示例代码请查看官方文档

https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-fa-calls-pa-examples-0000000000618000

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
1
收藏 2
回复
举报
2条回复
按时间正序
/
按时间倒序
Hagon
Hagon
回复
2022-2-14 13:42:38
Hagon
Hagon
回复
2022-2-14 13:43:09
回复
    相关推荐