回复
HarmonyOS API:综合示例
joytrian
发布于 2023-4-13 19:33
浏览
0收藏
版本:v3.1 Beta
综合示例
更新时间: 2023-02-17 09:19
CallAbility调用基本计算服务示例
- FA JavaScript端使用Internal Ability方式时,需要将对应的action.abilityType值改为ABILITY_TYPE_INTERNAL。
// 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方式)功能代码实现:在java目录下新建一个Service Ability,文件命名为ComputeServiceAbility.java
package com.example.hiaceservice;
// 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;
public class ComputeServiceAbility extends Ability {
// 定义日志标签
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");
private MyRemote remote = new MyRemote();
// FA在请求PA服务时会调用Ability.connectAbility连接PA,连接成功后,需要在onConnect返回一个remote对象,供FA向PA发送消息
@Override
protected IRemoteObject onConnect(Intent intent) {
super.onConnect(intent);
return remote.asObject();
}
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;
}
}
}
请求参数代码:
RequestParam.java
public class RequestParam {
private int firstNum;
private int secondNum;
public int getFirstNum() {
return firstNum;
}
public void setFirstNum(int firstNum) {
this.firstNum = firstNum;
}
public int getSecondNum() {
return secondNum;
}
public void setSecondNum(int secondNum) {
this.secondNum = secondNum;
}
}
- PA端(Internal Ability方式)功能代码实现(以下代码可以使用js2java-codegen工具自动生成):在java目录下新建一个Service Ability,文件命名为ComputeInternalAbility.java
package com.example.hiaceservice;
// ohos相关接口包
import ohos.ace.ability.AceInternalAbility;
import ohos.app.AbilityContext;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.IRemoteObject;
import ohos.rpc.MessageOption;
import ohos.rpc.MessageParcel;
import ohos.rpc.RemoteException;
import ohos.utils.zson.ZSONObject;
import java.util.HashMap;
import java.util.Map;
public class ComputeInternalAbility extends AceInternalAbility {
private static final String BUNDLE_NAME = "com.example.hiaceservice";
private static final String ABILITY_NAME = "com.example.hiaceservice.ComputeInternalAbility";
private static final int SUCCESS = 0;
private static final int ERROR = 1;
private static final int PLUS = 1001;
// 定义日志标签
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");
private static ComputeInternalAbility instance;
private AbilityContext abilityContext;
// 如果多个Ability实例都需要注册当前InternalAbility实例,需要更改构造函数,设定自己的bundleName和abilityName
public ComputeInternalAbility() {
super(BUNDLE_NAME, ABILITY_NAME);
}
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());
// SYNC
if (option.getFlags() == MessageOption.TF_SYNC) {
reply.writeString(ZSONObject.toZSONString(result));
} else {
// ASYNC
MessageParcel responseData = MessageParcel.obtain();
responseData.writeString(ZSONObject.toZSONString(result));
IRemoteObject remoteReply = reply.readRemoteObject();
try {
remoteReply.sendRequest(0, responseData, MessageParcel.obtain(), new MessageOption());
} catch (RemoteException exception) {
return false;
} finally {
responseData.reclaim();
}
}
break;
}
default: {
Map<String, Object> result = new HashMap<String, Object>();
result.put("abilityError", ERROR);
reply.writeString(ZSONObject.toZSONString(result));
return false;
}
}
return true;
}
/**
* Internal ability 注册接口。
*/
public static void register(AbilityContext abilityContext) {
instance = new ComputeInternalAbility();
instance.onRegister(abilityContext);
}
private void onRegister(AbilityContext abilityContext) {
this.abilityContext = abilityContext;
this.setInternalAbilityHandler((code, data, reply, option) -> {
return this.onRemoteRequest(code, data, reply, option);
});
}
/**
* Internal ability 注销接口。
*/
public static void unregister() {
instance.onUnregister();
}
private void onUnregister() {
abilityContext = null;
this.setInternalAbilityHandler(null);
}
}
Internal Ability注册:修改继承AceAbility工程中的代码
public class MainAbility extends AceAbility {
@Override
public void onStart(Intent intent) {
// 注册, 如果需要在Page初始化(onInit或之前)时调用AceInternalAbility的能力,注册操作需要在super.onStart之前进行
ComputeInternalAbility.register(this);
...
super.onStart(intent);
}
@Override
public void onStop() {
// 注销
ComputeInternalAbility.unregister();
super.onStop();
}
}
SubscribeAbilityEvent/UnsubscribeAbilityEvent订阅以及取消订阅服务示例
- FA JavaScript端使用Internal Ability方式时,需要将对应的action.abilityType值改为ABILITY_TYPE_INTERNAL。
// 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_SUBSCRIBE = 1005;
const ACTION_MESSAGE_CODE_UNSUBSCRIBE = 1006;
export default {
subscribe: async function() {
var action = {};
action.bundleName = 'com.example.hiaceservice';
action.abilityName = 'com.example.hiaceservice.ComputeServiceAbility';
action.messageCode = ACTION_MESSAGE_CODE_SUBSCRIBE;
action.abilityType = ABILITY_TYPE_EXTERNAL;
action.syncOption = ACTION_SYNC;
var result = await FeatureAbility.subscribeAbilityEvent(action, function(callbackData) {
var callbackJson = JSON.parse(callbackData);
console.info('eventData is: ' + JSON.stringify(callbackJson.data));
this.eventData = JSON.stringify(callbackJson.data);
});
var ret = JSON.parse(result);
if (ret.code == 0) {
console.info('subscribe success, result:' + result);
} else {
console.error('subscribe error, result:' + result);
}
},
unsubscribe: async function() {
var action = {};
action.bundleName = 'com.example.hiaceservice';
action.abilityName = 'com.example.hiaceservice.ComputeServiceAbility';
action.messageCode = ACTION_MESSAGE_CODE_UNSUBSCRIBE;
action.abilityType = ABILITY_TYPE_EXTERNAL;
action.syncOption = ACTION_SYNC;
var result = await FeatureAbility.unsubscribeAbilityEvent(action);
var ret = JSON.parse(result);
if (ret.code == 0) {
console.info('unsubscribe success, result: ' + result);
} else {
console.error('unsubscribe error, result: ' + result);
}
},
}
- PA端(Ability方式)功能代码实现:在java目录下新建一个Service Ability,文件命名为ComputeServiceAbility.java
// ohos相关接口包
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.rpc.IRemoteBroker;
import ohos.rpc.IRemoteObject;
import ohos.rpc.RemoteException;
import ohos.rpc.RemoteObject;
import ohos.rpc.MessageParcel;
import ohos.rpc.MessageOption;
import ohos.utils.zson.ZSONObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ComputeServiceAbility extends Ability {
private MyRemote remote = new MyRemote();
// FA在请求PA服务时会调用AbilityconnectAbility连接PA,连接成功后,需要在onConnect返回一个remote对象,供FA向PA发送消息
@Override
protected IRemoteObject onConnect(Intent intent) {
super.onConnect(intent);
return remote.asObject();
}
class MyRemote extends RemoteObject implements IRemoteBroker {
private static final int SUCCESS = 0;
private static final int SUBSCRIBE = 1005;
private static final int UNSUBSCRIBE = 1006;
// 支持多FA订阅,如果仅支持单FA订阅,可直接使用变量存储:private IRemoteObject remoteObjectHandler;
private Set<IRemoteObject> remoteObjectHandlers = new HashSet<IRemoteObject>();
private Thread thread = null;
MyRemote() {
super("MyService_MyRemote");
}
@Override
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) throws RemoteException {
switch (code) {
// 开启订阅,保存对端的remoteHandler,用于上报数据
case SUBSCRIBE: {
// 如果仅支持单FA订阅,可直接覆盖:remoteObjectHandler = data.readRemoteObject();
remoteObjectHandlers.add(data.readRemoteObject());
startNotify();
Map<String, Object> result = new HashMap<String, Object>();
result.put("code", SUCCESS);
reply.writeString(ZSONObject.toZSONString(result));
break;
}
// 取消订阅,置空对端的remoteHandler
case UNSUBSCRIBE: {
// 如果仅支持单FA订阅,可直接置空:remoteObjectHandler = null;
remoteObjectHandlers.clear();
thread.stop();
Map<String, Object> result = new HashMap<String, Object>();
result.put("code", SUCCESS);
reply.writeString(ZSONObject.toZSONString(result));
break;
}
default: {
reply.writeString("service not defined");
return false;
}
}
return true;
}
public void startNotify() {
thread = new Thread(() -> {
while (true) {
try {
Thread.sleep(5 * 100);
testReportEvent();
} catch (RemoteException | InterruptedException e) {
break;
}
}
});
thread.start();
}
private void testReportEvent() throws RemoteException {
MessageParcel data = MessageParcel.obtain();
MessageParcel reply = MessageParcel.obtain();
MessageOption option = new MessageOption();
Map<String, Object> event = new HashMap<String, Object>();
event.put("abilityEvent", "test event!");
data.writeString(ZSONObject.toZSONString(event));
// 如果仅支持单FA订阅,可直接触发回调:remoteObjectHandler.sendRequest(100, data, reply, option);
for (IRemoteObject item : remoteObjectHandlers) {
item.sendRequest(100, data, reply, option);
}
reply.reclaim();
data.reclaim();
}
@Override
public IRemoteObject asObject() {
return this;
}
}
}
- PA端(Internal Ability)功能代码实现:在java目录下新建一个Service Ability,文件命名为ComputeInternalAbility.java
// ohos相关接口包
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;
import ohos.utils.zson.ZSONObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ComputeInternalAbility extends AceInternalAbility{
private static final String BUNDLE_NAME = "com.example.hiaceservice";
private static final String ABILITY_NAME = "com.example.hiaceservice.ComputeServiceAbility";
private static final int SUCCESS = 0;
private static final int SUBSCRIBE = 1005;
private static final int UNSUBSCRIBE = 1006;
private static ComputeInternalAbility instance;
private AbilityContext abilityContext;
// 支持多FA订阅,如果仅支持单FA订阅,可直接使用变量存储:private IRemoteObject remoteObjectHandler;
private Set<IRemoteObject> remoteObjectHandlers = new HashSet<IRemoteObject>();
private Thread thread = null;
public ComputeInternalAbility() {
super(BUNDLE_NAME, ABILITY_NAME);
}
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) throws RemoteException {
switch (code) {
// 开启订阅,保存对端的remoteHandler,用于上报数据
case SUBSCRIBE: {
// 如果仅支持单FA订阅,可直接覆盖:remoteObjectHandler = data.readRemoteObject();
remoteObjectHandlers.add(data.readRemoteObject());
startNotify();
Map<String, Object> result = new HashMap<String, Object>();
result.put("code", SUCCESS);
// SYNC
if (option.getFlags() == MessageOption.TF_SYNC) {
reply.writeString(ZSONObject.toZSONString(result));
} else {
//ASYNC
MessageParcel responseData = MessageParcel.obtain();
responseData.writeString(ZSONObject.toZSONString(result));
IRemoteObject remoteReply = reply.readRemoteObject();
try {
remoteReply.sendRequest(0, responseData, MessageParcel.obtain(), new MessageOption());
responseData.reclaim();
} catch (RemoteException exception) {
return false;
}
}
break;
}
// 取消订阅,置空对端的remoteHandler
case UNSUBSCRIBE: {
// 如果仅支持单FA订阅,可直接置空:remoteObjectHandler = null;
remoteObjectHandlers.clear();
thread.stop();
Map<String, Object> result = new HashMap<String, Object>();
result.put("code", SUCCESS);
// SYNC
if (option.getFlags() == MessageOption.TF_SYNC) {
reply.writeString(ZSONObject.toZSONString(result));
} else {
//ASYNC
MessageParcel responseData = MessageParcel.obtain();
responseData.writeString(ZSONObject.toZSONString(result));
IRemoteObject remoteReply = reply.readRemoteObject();
try {
remoteReply.sendRequest(0, responseData, MessageParcel.obtain(), new MessageOption());
responseData.reclaim();
} catch (RemoteException exception) {
return false;
}
}
break;
}
default: {
reply.writeString("Service not defined");
return false;
}
}
return true;
}
public void startNotify() {
thread = new Thread(() -> {
while (true) {
try {
Thread.sleep(5 * 100);
testReportEvent();
} catch (RemoteException | InterruptedException e) {
break;
}
}
});
thread.start();
}
private void testReportEvent() throws RemoteException {
MessageParcel data = MessageParcel.obtain();
MessageParcel reply = MessageParcel.obtain();
MessageOption option = new MessageOption();
Map<String, Object> event = new HashMap<String, Object>();
event.put("abilityEvent", "test event!");
data.writeString(ZSONObject.toZSONString(event));
// 如果仅支持单FA订阅,可直接触发回调:remoteObjectHandler.sendRequest(100, data, reply, option);
for (IRemoteObject item : remoteObjectHandlers) {
item.sendRequest(100, data, reply, option);
}
reply.reclaim();
data.reclaim();
}
/**
* Internal ability 注册接口。
*/
public static void register(AbilityContext abilityContext) {
instance = new ComputeInternalAbility();
instance.onRegister(abilityContext);
}
private void onRegister(AbilityContext abilityContext) {
this.abilityContext = abilityContext;
this.setInternalAbilityHandler((code, data, reply, option) -> {
return this.onRemoteRequest(code, data, reply, option);
});
}
/**
* Internal ability 注销接口。
*/
public static void unregister() {
instance.onUnregister();
}
private void onUnregister() {
abilityContext = null;
this.setInternalAbilityHandler(null);
}
}
Internal Ability注册:修改继承AceAbility工程中的代码
public class HiAceInternalAbility extends AceAbility {
@Override
public void onStart(Intent intent) {
// 注册, 如果需要在Page初始化(onInit或之前)时调用AceInternalAbility的能力,注册操作需要在super.onStart之前进行
ComputeInternalAbility.register(this);
super.onStart(intent);
}
@Override
public void onStop() {
// 注销
ComputeInternalAbility.unregister();
super.onStop();
}
}
已于2023-4-13 19:33:04修改
赞
收藏
回复
相关推荐