JSFA調(diào)用PA之三Ability調(diào)用方式
原創(chuàng)??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??
??https://harmonyos.51cto.com??
引言
- 【FFH】JSFA調(diào)用PA(一)Ability概念及Ability與Internal Ability
- 【FFH】JSFA調(diào)用PA(二) Internal Ability調(diào)用方式
上兩篇文章我們已經(jīng)了解到了Ability的概念,還有JS FA調(diào)用Java PA兩種方式,Ability和Internal Ability的區(qū)別,還有第二篇文章對InternalAbility調(diào)用方式的講解。
接下來我們借助官方文檔的案例來解讀一下 Ability 調(diào)用方式的具體實現(xiàn)方法。
在此之前,我們先來看一下一些相關(guān)概念。
相關(guān)概念
RPC( Remote Procedure Call)
Ability方式中,與FA通過RPC方式通信,先來了解一下什么是RPC,RPC 是 Remote Procedure Call ,翻譯過來就是遠程過程調(diào)用,說白了就是一個機器遠程調(diào)用并執(zhí)行另一個機器上的函數(shù)。
所以他是個比較寬泛的概念,其中我們經(jīng)常用到的HTTP協(xié)議就屬于常見的一種RPC實現(xiàn)方式。
在HarmonyOS有很多地方都用到了RPC方式通信,比如跨設(shè)備調(diào)用,遠程拉起FA,F(xiàn)A的遷移流轉(zhuǎn)等等。
Intent
了解完什么是RPC,那么RPC具體是通過什么讓發(fā)送方和接收機方知道要干什么的呢?其實就是接下來我們要說的對象之間傳遞信息的載體—Intent。
開發(fā)者的PA首次被FA連接時回調(diào),并返回IRemoteObject對象,用于后續(xù)的業(yè)務(wù)通信。開發(fā)者需要繼承Ability類并重寫onConnect(Intent: intent)方法,其中該方法的參數(shù)就是Intent,所以他到底是拿來干嘛的呢?
在HarmonyOS中提供了Intent機制來協(xié)助Ability之間的通信,例如,當(dāng)一個Ability需要啟動另一個Ability時,或者一個AbilitySlice需要導(dǎo)航到另一個AbilitySlice時。
Intent是一個將要執(zhí)行的動作的抽象的描述,在HarmonyOS中由以下元素構(gòu)成:
用大白話講,Intent就是作為Ability之間交流的粘合劑,接收方Ability可以從Intent獲得到發(fā)送方發(fā)送了什么請求。
JS FA調(diào)用Java PA — Ability調(diào)用方式
接下來進入正題。
JS FA端
這部分我們就不細說,因為和InternalAbility的實現(xiàn)方法差不多,只是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方式)
這里我們還是以官方文檔的案例為參考,我們對官方案例進行一個步驟分解,以方便理解
1.導(dǎo)入相關(guān)ohos接口包
// ohos相關(guān)接口包
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.創(chuàng)建一個繼承Ability的類并且重寫onConnect方法
創(chuàng)建完這個類之后,先重寫onConnect(Intent: intent)方法,并且在onConnect返回一個remote對象,供FA向PA發(fā)送消息。
public class ComputeServiceAbility extends Ability {
// 定義日志標(biāo)簽
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "MY_TAG");
// FA在請求PA服務(wù)時會調(diào)用Ability.connectAbility連接PA,連接成功后,需要在onConnect返回一個remote對象,供FA向PA發(fā)送消息
@Override
protected IRemoteObject onConnect(Intent intent) {
super.onConnect(intent);
return remote.asObject();
}
}
3.繼承RemoteObject類重寫方法完成業(yè)務(wù)邏輯
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.");
}
// 返回結(jié)果當(dāng)前僅支持String,對于復(fù)雜結(jié)構(gòu)可以序列化為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;
}
}
完整示例代碼請查看官方文檔
??51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)??
??https://harmonyos.51cto.com??