评论

收藏

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

移动开发 移动开发 发布于:2021-07-13 18:53 | 阅读数:467 | 评论:0

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

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

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

DSC0000.png
  :::
  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

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

FA调用PA开发方法

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

DSC0002.png
  :::
  ::: 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
关注下面的标签,发现更多相似文章