关于鸿蒙JS的FA调用JAVA的PA需要注意的地方

790 阅读2分钟

前言

官网虽然给了一个综合示例,但看起来比较繁琐,我在这给大家精简一下,顺便提醒几个需要注意的小地方。

JS代码

为了方便大家理解,我就把实现代码也写到Page中的JS文件里了,实际开发还是单独写个接口文件的好。

下面就是在JS层的代码,分别调用CallAbility和subscribeAbilityEvent。这两个的区别也很好理解,CallAbility就是用于一次请求,JS这边就只能收到一次响应。而subscribeAbilityEvent建立订阅后,只要你在JAVA层一直发消息,这边的JS也能一直收到到数据去处理,直到你取消订阅(取消订阅我有点懒,没写)。有一点需要说明一下就是JAVA那边只能发String类型的数据过来,也可能是我菜,我调用过别的数据类型方法发送,JS层一直没收到数据。JS层CallAbility的回调里接收数据,你在JAVA层发送的什么样的String,这边就接收到什么数据(java发送 "1", js就会收到 "1")。而subscribeAbilityEvent不是,你在java层发送的String,在JS接收的时候会是一个Json格式的。比如java发送 "2",JS会收到{"code":0,"data":2}。

const MESSAGE_CODE = {
  CALL_ABILITY: 1001,
  SUB_ABILITY: 1002,
}

const ACTION = Object.freeze({
  bundleName: 'com.example.myapplicatio1sn',
  abilityName: 'com.example.myapplicatio1sn.InternalAbility',
  // abilityType: 0-Ability; 1-Internal Ability
  abilityType: 1,
  // syncOption(Optional, default sync): 0-Sync; 1-Async
  syncOption: 0
});

const TAG = "ohosTest";

export default {

  onShow() {
    this.callAbility(result => {
      console.info(`${TAG} onShow callAbility result ${result}`);
    });

    this.subAbility(result => {
      console.info(`${TAG} onShow subAbility result ${result}`);
    })
  },

  callAbility(callback) {
    var action = this.setAction(MESSAGE_CODE.CALL_ABILITY);
    FeatureAbility.callAbility(action).then(result => {
      console.info(`${TAG} callAbility get result ${result}`);
      callback(result);
    });
  },

  subAbility(callback) {
    var action = this.setAction(MESSAGE_CODE.SUB_ABILITY);
    FeatureAbility.subscribeAbilityEvent(action, result => {
      console.info(`${TAG} subscribeAbilityEvent get result ${result}`);
      callback(result);
    })
  },

  setAction(code) {
    return Object.assign({}, ACTION, {
      messageCode: code
    });
  }
}

JAVA代码

如果JS使用callAbility调用,在JAVA层直接使用 reply.writeString("")方法就可以发送给JS层。
如果JS使用subscribeAbilityEvent调用,这里就有坑了

最好先定义全局的IRemoteObject remoteObject对象,如果你在某些方法的回调里直接获取remoteObject对象会是null(这里我就想说,这编译器不会报空指针你敢信??!!)。
然后调用remoteObject.sendRequest(0, response, obtain, new MessageOption())发送给JS层。把你要发送的数据放到response中,response.writeString("")就完成了

最后不要忘了在MainAbility中注册。

package com.example.myapplicatio1sn;

import ohos.ace.ability.AceInternalAbility;
import ohos.app.AbilityContext;
import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;

public class InternalAbility extends AceInternalAbility implements AceInternalAbility.AceInternalAbilityHandler {

    private static final String BUNDLE_NAME = "com.example.myapplicatio1sn";

    private static final String ABILITY_NAME = "com.example.myapplicatio1sn.InternalAbility";

    private static InternalAbility instance;
    private AbilityContext abilityContext;
    private IRemoteObject remoteObject;

    public InternalAbility() {
        super(BUNDLE_NAME, ABILITY_NAME);
    }

    public static void register(AbilityContext abilityContext) {
        instance = new InternalAbility();
        instance.onRegister(abilityContext);
    }

    private void onRegister(AbilityContext abilityContext) {
        this.abilityContext = abilityContext;
        this.setInternalAbilityHandler(this::onRemoteRequest);
    }

    public static void unregister() {
        instance.onUnregister();
    }

    private void onUnregister() {
        abilityContext = null;
        this.setInternalAbilityHandler(null);
    }

    @Override
    public boolean onRemoteRequest(int code, MessageParcel request, MessageParcel reply, MessageOption messageOption) {
        remoteObject = request.readRemoteObject();
        System.out.println("ohosTest onRemoteRequest code " + code);
        if (code == 1001) {
            reply.writeString("111111");
        } else {
            MessageParcel response = MessageParcel.obtain();
            MessageParcel obtain = MessageParcel.obtain();
            response.writeString("22222");
            try {
                remoteObject.sendRequest(0, response, obtain, new MessageOption());
            } catch (RemoteException exception) {
                System.out.println(exception.toString());
            }
        }

        return true;
    }
}
public class MainAbility extends AceAbility {
    @Override
    public void onStart(Intent intent) {
        InternalAbility.register(this);
        super.onStart(intent);
    }

    @Override
    public void onStop() {
        super.onStop();
    }
}

image.png