绝代码农 发表于 2021-7-13 18:53:39

JS UI框架下FA与PA是如何交互的

  上一篇“HarmonyOS UI框架关键技术解析”中,给大家介绍了基于JS/JAVA UI框架开发简单业务的方法。那么对于复杂业务,在当前HarmonyOS版本下,如何基于JS UI框架来开发呢?

JS UI框架下FA与PA交互的使用场景

  通常一个典型使用JS UI框架的HarmonyOS应用开发模型如下图1所示:
  ::: hljs-center


  :::
  JS UI框架提供的声明式编程,使应用开发更加简单,但当前HarmonyOS JS API还不够丰富,无法处理数据等更复杂的业务。为了达到处理复杂业务,同时保证业务数据和UI的解耦,一般会将复杂逻辑放到PA中即JAVA端实现,而界面交互则放到FA中的UI部分即JS端实现,如图1所示。
  这就涉及到FA(JS端)与PA(JAVA端)的交互,为此,Harmony OS JS UI框架提供了JS FA(Feature Ability)调用JAVA PA(Particle Ability)的机制,该机制提供了一种通道来传递方法调用、处理数据返回以及订阅事件上报。
  下面我们通过一两个例子来解释该方法涉及的技术原理。

HarmonyOS下FA调用PA机制

  
接口拓展机制


  为支持ACE开发框架一次开发,跨平台运行的目标,采用了接口拓展机制打通前端应用层和后端平台层。JS UI框架提供了一种自动封装平台能力扩展API的机制,让应用开发者轻松调用API即能完成JS端到JAVA端的传递方法调用、处理数据返回以及订阅事件上报。
  ::: hljs-center


  :::
  FA调用PA注意事项:
  ● JS和JAVA侧定义好的“方法调用”在对外开放后,需要保证前向兼容性。
  ● 序列化数据默认最大支持200KB数据量,若需要传输大数据,可以使用对应接口ohos.utils.Parcel.setCapacity()调整buffer容量大小。

FA调用PA开发方法

  下面来给大家详细介绍JS FA调用JAVA PA的开发方法。
  ::: hljs-center


  :::
  ::: hljs-center
  图4 JS FA调用JAVA PA过程(Ability方式)
  :::
  1.FA JS端指定PA的调用方式及相关消息码和内容,调用PA(订阅PA类似)。设置bundleName,abilityName,abilityType等。
  2.PA JAVA端响应:
  通过Ability方式拉起的PA继承自Ability,FA在请求PA服务时会连接到PA,连接成功后,PA在onConnect返回一个remote对象(RemoteObject),用于FA向PA发送消息。remote对象实现onRemoteRequest方法,用于响应FA端的请求。
  示例代码如下:e.g.两数求和
  ◆ FA端 (Ability方式)
// 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;
   
    // 请求参数,abilityName、bundleName、messageCode、abilityType、actionData需要求和的2个入参   
    var action = {};   
    action.bundleName = 'com.example.hiaceservice';   
    action.abilityName = 'com.example.hiaceservice.ComputeServiceAbility';   
    action.messageCode = ACTION_MESSAGE_CODE_PLUS;
    action.data = actionData;
    // 使用ability方式   
    action.abilityType = ABILITY_TYPE_EXTERNAL;   
    action.syncOption = ACTION_SYNC;
   
    // FA调用PA   
    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方式)
public class ComputeServiceAbility extends Ability {
private MyRemote remote = new MyRemote();
// FA在请求PA服务时会连接PA,连接成功后,需要在onConnect返回一个remote对象,供FA向PA发送消息
@Override
protected IRemoteObject onConnect(Intent intent) {   
    super.onConnect(intent);   
    return remote.asObject();
}
// remote对象的实现,完成消息请求处理,回传
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) {
      // 消息码PLUS      
      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.");         
      }         
      
      // 返回结果设置         
      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;   
   }
}
}
Internal Ability调用方式流程

  ::: hljs-center
页: [1]
查看完整版本: JS UI框架下FA与PA是如何交互的