自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā)
本文介紹了JS FA(Feature Ability)調(diào)用JAVA PA(Particle Ability)的機(jī)制和使用場景,基于JS UI框架開發(fā)的應(yīng)用可以使用該機(jī)制完成更豐富的功能。

[[411492]]

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

上一篇“HarmonyOS UI框架關(guān)鍵技術(shù)解析”中,給大家介紹了基于JS/JAVA UI框架開發(fā)簡單業(yè)務(wù)的方法。那么對于復(fù)雜業(yè)務(wù),在當(dāng)前HarmonyOS版本下,如何基于JS UI框架來開發(fā)呢?

JS UI框架下FA與PA交互的使用場景

通常一個典型使用JS UI框架的HarmonyOS應(yīng)用開發(fā)模型如下圖1所示:

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

圖1 典型應(yīng)用開發(fā)模型

HarmonyOS的用戶應(yīng)用程序包APP由一個或多個Hap包組成。每個Hap可以包含一個或多個Ability。Ability分為兩種類型:Feature Ability(簡稱FA)和Particle Ability(簡稱PA),F(xiàn)A和PA是HarmonyOS應(yīng)用的基本組成單元,能夠?qū)崿F(xiàn)特定的業(yè)務(wù)功能。FA有UI界面,而PA無UI界面。FA有多種展現(xiàn)形式,如普通界面形式Page Ability,服務(wù)卡片形式Form等,一般使用JS 語言實(shí)現(xiàn)前臺界面。PA支持ServiceAbility和Data Ability。ServiceAbility提供后臺運(yùn)行任務(wù)的能力,如處理復(fù)雜后臺任務(wù)等。Data Ability用于對外部提供統(tǒng)一的數(shù)據(jù)訪問抽象。這兩個Ability一般使用Java 語言實(shí)現(xiàn)。

當(dāng)前HarmonyOS Ability具體分類信息如下:

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

JS UI框架提供的聲明式編程,使應(yīng)用開發(fā)更加簡單,但當(dāng)前HarmonyOS JS API還不夠豐富,無法處理數(shù)據(jù)等更復(fù)雜的業(yè)務(wù)。為了達(dá)到處理復(fù)雜業(yè)務(wù),同時保證業(yè)務(wù)數(shù)據(jù)和UI的解耦,一般會將復(fù)雜邏輯放到PA中即JAVA端實(shí)現(xiàn),而界面交互則放到FA中的UI部分即JS端實(shí)現(xiàn),如圖1所示。

這就涉及到FA(JS端)與PA(JAVA端)的交互,為此,Harmony OS JS UI框架提供了JS FA(Feature Ability)調(diào)用JAVA PA(Particle Ability)的機(jī)制,該機(jī)制提供了一種通道來傳遞方法調(diào)用、處理數(shù)據(jù)返回以及訂閱事件上報(bào)。

下面我們通過一兩個例子來解釋該方法涉及的技術(shù)原理。

HarmonyOS下FA調(diào)用PA機(jī)制

接口拓展機(jī)制

為支持ACE開發(fā)框架一次開發(fā),跨平臺運(yùn)行的目標(biāo),采用了接口拓展機(jī)制打通前端應(yīng)用層和后端平臺層。JS UI框架提供了一種自動封裝平臺能力擴(kuò)展API的機(jī)制,讓應(yīng)用開發(fā)者輕松調(diào)用API即能完成JS端到JAVA端的傳遞方法調(diào)用、處理數(shù)據(jù)返回以及訂閱事件上報(bào)。

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

圖2 模塊框架模型

如圖2所示,當(dāng)前HarmonyOS支持JS作為前端應(yīng)用開發(fā)語言,提供API接口,供開發(fā)者實(shí)現(xiàn)業(yè)務(wù)邏輯,通過類似接口拓展機(jī)制將JS層的參數(shù)傳遞到平臺層(Native),同時在平臺層提供插件代碼(Plugin Native code)供三方平臺實(shí)現(xiàn)業(yè)務(wù)邏輯。

 JS FrameWork

提供API用于傳遞方法調(diào)用,數(shù)據(jù)流通信,以及訂閱事件回調(diào)。并通過JsBridge橋接起C++ 與JS,JsBridge主要負(fù)責(zé)加載JS代碼,運(yùn)行在QJS Engine上,將JS代碼通過全局函數(shù)橋接到C++ 上,并將C++的結(jié)果返回給JS層。

 QJS Engine

QuickJS 是一個輕量且可嵌入的 JavaScript 引擎,包括模塊、異步生成器和代理。

 ACE Framework

將JS的消息往平臺層透傳,將JS數(shù)據(jù)轉(zhuǎn)換成C++ 類型的數(shù)據(jù),再通過C++ 與JAVA的JNI接口類,將C++的數(shù)據(jù)傳遞到JAVA側(cè),并接收J(rèn)AVA側(cè)返回的數(shù)據(jù)。

 Native

負(fù)責(zé)平臺層數(shù)據(jù)編解碼,并根據(jù)解碼后得到的FunctionName調(diào)用第三方開發(fā)者的插件代碼邏輯。

 HarmonyOS API

平臺層提供JAVA端API接口。開發(fā)者實(shí)現(xiàn)JAVA端對應(yīng)接口的業(yè)務(wù)邏輯。

HarmonyOS下FA調(diào)用PA機(jī)制

JS UI框架當(dāng)前提供了Ability和Internal Ability兩種FA調(diào)用PA的方式:

  •  Ability調(diào)用方式:擁有獨(dú)立的Ability生命周期,F(xiàn)A使用遠(yuǎn)端進(jìn)程通信拉起并請求PA服務(wù),適用于基本服務(wù)PA有多個FA調(diào)用或者PA在后臺獨(dú)立運(yùn)行的場景。
  •  Internal Ability調(diào)用方式:PA與FA共進(jìn)程,PA和FA采用內(nèi)部函數(shù)調(diào)用的方式進(jìn)行通信,適用于對服務(wù)響應(yīng)時延要求較高的場景。該方式下PA不支持其他FA訪問調(diào)用。

這兩種調(diào)用方式在代碼中可通過abilityType來標(biāo)識,具體使用差異見下表:

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

FA調(diào)用PA注意事項(xiàng):

  •  JS和JAVA側(cè)定義好的“方法調(diào)用”在對外開放后,需要保證前向兼容性。
  •  序列化數(shù)據(jù)默認(rèn)最大支持200KB數(shù)據(jù)量,若需要傳輸大數(shù)據(jù),可以使用對應(yīng)接口ohos.utils.Parcel.setCapacity()調(diào)整buffer容量大小。

FA調(diào)用PA開發(fā)方法

下面來給大家詳細(xì)介紹JS FA調(diào)用JAVA PA的開發(fā)方法。

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

圖3 FA調(diào)用PA開發(fā)方法

如圖3所示,當(dāng)FeatureAbility Plugin收到JS調(diào)用請求后,系統(tǒng)根據(jù)開發(fā)者在JS接口中設(shè)置的參數(shù)如指定的abilityType(Ability或Internal Ability),來選擇對應(yīng)的方式進(jìn)行處理。開發(fā)者在onRemoteRequest()中實(shí)現(xiàn)PA提供的業(yè)務(wù)邏輯,不同的業(yè)務(wù)通過業(yè)務(wù)碼來區(qū)分。

 FA端

1.Channel JS API提供以下模塊能力:

  •  ModuleGroup

用于傳遞方法調(diào)用的類,通常用于上層應(yīng)用者調(diào)用native中的某個方法而定義使用。調(diào)用callNative()方法即可將function以及對應(yīng)的參數(shù)傳遞到平臺層,需要在Native層也適配相應(yīng)的邏輯代碼。

簡言之,即ModuleGroup實(shí)現(xiàn)JS調(diào)用JAVA方法,提供的JS API如下:

√ 調(diào)用PA能力,F(xiàn)eatureAbility.callAbility(OBJECT)

  •  EventGroup

用于數(shù)據(jù)流通信,通常用于平臺層觸發(fā)的Native事件通知應(yīng)用層。在應(yīng)用層調(diào)用subscribe()方法注冊回調(diào)事件啟動監(jiān)聽平臺,調(diào)用unSubscribe()取消平臺監(jiān)聽。第三方開發(fā)者在平臺層需要適配相應(yīng)的邏輯代碼。

簡言之,即EventGroup實(shí)現(xiàn)JAVA回調(diào)JS,提供的JS API如下:

  • 訂閱PA能力,F(xiàn)eatureAbility.subscribeAbilityEvent(OBJECT, Function)
  •  取消訂閱PA能力,F(xiàn)eatureAbility.unsubscribeAbilityEvent(OBJECT)

2.FeatureAbility Plugin

主要完成方法調(diào)用、數(shù)據(jù)流的參數(shù)傳遞(編解碼)、線程切換、JNI轉(zhuǎn)換等處理。

其主要提供以下2個重點(diǎn)模塊:

  •  Internal Ability Manager

用于Internal Ability的管理,包括注冊管理等,注冊后的Internal Ability與FA共生命周期。

  •  Connection Manager

JS端與JAVA端通過接口擴(kuò)展機(jī)制進(jìn)行通信,通過bundleName和abilityName來進(jìn)行關(guān)聯(lián)。

 PA端

PA端提供以下兩類接口:

  •  IRemoteObject.onRemoteRequest(int, MessageParcel, MessageParcel, MessageOption)

Ability調(diào)用方式,F(xiàn)A使用遠(yuǎn)端進(jìn)程通信拉起并請求PA服務(wù)。

  •  AceInternalAbility.AceInternalAbilityHandler.onRemoteRequest(int, MessageParcel, MessageParcel, MessageOption)

Internal Ability調(diào)用方式,采用內(nèi)部函數(shù)調(diào)用的方式和FA進(jìn)行通信。

Ability調(diào)用方式流程

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

圖4 JS FA調(diào)用JAVA PA過程(Ability方式)

1.FA JS端指定PA的調(diào)用方式及相關(guān)消息碼和內(nèi)容,調(diào)用PA(訂閱PA類似)。設(shè)置bundleName,abilityName,abilityType等。

2.PA JAVA端響應(yīng):

通過Ability方式拉起的PA繼承自Ability,F(xiàn)A在請求PA服務(wù)時會連接到PA,連接成功后,PA在onConnect返回一個remote對象(RemoteObject),用于FA向PA發(fā)送消息。remote對象實(shí)現(xiàn)onRemoteRequest方法,用于響應(yīng)FA端的請求。

示例代碼如下:e.g.兩數(shù)求和

 FA端 (Ability方式)

  1. // abilityType: 0-Ability; 1-Internal Ability 
  2. const ABILITY_TYPE_EXTERNAL = 0; 
  3. const ABILITY_TYPE_INTERNAL = 1; 
  4. // syncOption(Optional, default sync): 0-Sync; 1-Async 
  5. const ACTION_SYNC = 0; 
  6. const ACTION_ASYNC = 1; 
  7. const ACTION_MESSAGE_CODE_PLUS = 1001; 
  8. export default {   
  9.   plus: async function() {     
  10.     var actionData = {};     
  11.     actionData.firstNum = 1024;     
  12.     actionData.secondNum = 2048; 
  13.      
  14.     // 請求參數(shù),abilityName、bundleName、messageCode、abilityType、actionData需要求和的2個入?yún)?nbsp;    
  15.     var action = {};     
  16.     action.bundleName = 'com.example.hiaceservice';     
  17.     action.abilityName = 'com.example.hiaceservice.ComputeServiceAbility';     
  18.     action.messageCode = ACTION_MESSAGE_CODE_PLUS; 
  19.     action.data = actionData; 
  20.     // 使用ability方式     
  21.     action.abilityType = ABILITY_TYPE_EXTERNAL;     
  22.     action.syncOption = ACTION_SYNC; 
  23.      
  24.     // FA調(diào)用PA     
  25.     var result = await FeatureAbility.callAbility(action);     
  26.     var ret = JSON.parse(result);     
  27.     if (ret.code == 0) {       
  28.       console.info('plus result is:' + JSON.stringify(ret.abilityResult));     
  29.     } else {       
  30.       console.error('plus error code:' + JSON.stringify(ret.code)); 
  31.     }   
  32.   } 

PA端(Ability方式)

  1. public class ComputeServiceAbility extends Ability {   
  2.   private MyRemote remote = new MyRemote();   
  3.   // FA在請求PA服務(wù)時會連接PA,連接成功后,需要在onConnect返回一個remote對象,供FA向PA發(fā)送消息   
  4.   @Override   
  5.   protected IRemoteObject onConnect(Intent intent) {     
  6.     super.onConnect(intent);     
  7.     return remote.asObject();   
  8.   } 
  9.   // remote對象的實(shí)現(xiàn),完成消息請求處理,回傳   
  10.   class MyRemote extends RemoteObject implements IRemoteBroker {     
  11.     private static final int SUCCESS = 0;     
  12.     private static final int ERROR = 1;     
  13.     private static final int PLUS = 1001;        
  14.      
  15.     MyRemote() {       
  16.       super("MyService_MyRemote");     
  17.     }     
  18.     @Override     
  19.     public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {       
  20.       switch (code) { 
  21.       // 消息碼PLUS         
  22.       case PLUS: { 
  23.         // 消息參數(shù)解析           
  24.         String dataStr = data.readString();           
  25.         RequestParam param = new RequestParam();           
  26.         try {                   
  27.           param = ZSONObject.stringToClass(dataStr, RequestParam.class);           
  28.         } catch (RuntimeException e) { 
  29.           HiLog.error(LABEL, "convert failed.");           
  30.         }           
  31.          
  32.         // 返回結(jié)果設(shè)置           
  33.         Map<String, Object> result = new HashMap<String, Object>();           
  34.         result.put("code", SUCCESS);           
  35.         result.put("abilityResult", param.getFirstNum() + param.getSecondNum());           
  36.         // 返回結(jié)果回傳           
  37.         reply.writeString(ZSONObject.toZSONString(result));           
  38.         break;         
  39.       }         
  40.       default: {           
  41.         Map<String, Object> result = new HashMap<String, Object>(); 
  42.         result.put("abilityError", ERROR);           
  43.         reply.writeString(ZSONObject.toZSONString(result));           
  44.         return false;         
  45.       }       
  46.     }       
  47.     return true;     
  48.   }     
  49.   @Override     
  50.   public IRemoteObject asObject() {       
  51.      return this;     
  52.    }  
  53.   } 

Internal Ability調(diào)用方式流程

JS UI框架下FA與PA是如何交互的-鴻蒙HarmonyOS技術(shù)社區(qū)

圖5 JS FA調(diào)用JAVA PA過程(Internal Ability方式)

1.FA JS端指定PA的調(diào)用方式及相關(guān)消息碼和內(nèi)容,調(diào)用PA(訂閱PA類似)。設(shè)置bundleName,abilityName,abilityType等。

2. PA JAVA端響應(yīng):

通過Internal Ability方式拉起的PA需要繼承自AceInternalAbility,且需要在AceAbility中注冊該Internal Ability(AceAbility中執(zhí)行register方法)。

PA中通過setInternalAbilityHandler方法注冊onRemoteRequest方法,用于響應(yīng)FA端的請求。

示例代碼如下:e.g.兩數(shù)求和

FA端(Internal Ability方式)

和使用ability方式代碼類似,區(qū)別是需要改變方式類型為Internal Ability:

action.abilityType = ABILITY_TYPE_INTERNAL;

 PA端(Internal Ability方式):

  1. //Internal Ability注冊:在MainAbility注冊 
  2. public class MainAbility extends AceAbility {   
  3.   @Override   
  4.   public void onStart(Intent intent) {     
  5.     // 注冊, 如果需要在Page初始化(onInit或之前)時調(diào)用AceInternalAbility的能力,注冊操作需要在super.onStart之前進(jìn)行     
  6.     ComputeInternalAbility.register(this);     
  7.     ...     
  8.     super.onStart(intent);   
  9.   }   
  10.   @Override    
  11.   public void onStop() {     
  12.     // 注銷     
  13.     ComputeInternalAbility.unregister();      
  14.     super.onStop();   
  15.   } 

在JAVA目錄下實(shí)現(xiàn)InternalAbility(此處為ComputeInternalAbility)

  1. public class ComputeInternalAbility extends AceInternalAbility {   
  2.   private static final String BUNDLE_NAME = "com.example.hiaceservice";   
  3.   private static final String ABILITY_NAME = "com.example.hiaceservice.ComputeInternalAbility";   
  4.   private static final int SUCCESS = 0;   
  5.   private static final int ERROR = 1;   
  6.   private static final int PLUS = 1001;   
  7.    
  8.   private static ComputeInternalAbility instance; 
  9.   private AbilityContext abilityContext;   
  10.   // 如果多個Ability實(shí)例都需要注冊當(dāng)前InternalAbility實(shí)例,需要更改構(gòu)造函數(shù),設(shè)定自己的bundleName和abilityName   
  11.   public ComputeInternalAbility() {     
  12.     super(BUNDLE_NAME, ABILITY_NAME);   
  13.   }   
  14.   public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) {     
  15.     switch (code) {       
  16.     case PLUS: {         
  17.       String dataStr = data.readString();         
  18.       RequestParam param = new RequestParam();         
  19.       try {                 
  20.         param = ZSONObject.stringToClass(dataStr, RequestParam.class);         
  21.       } catch (RuntimeException e) {                 
  22.         HiLog.error(LABEL, "convert failed.");         
  23.       }         
  24.        
  25.       // 返回結(jié)果當(dāng)前僅支持String,對于復(fù)雜結(jié)構(gòu)可以序列化為ZSON字符串上報(bào)         
  26.       Map<String, Object> result = new HashMap<String, Object>();         
  27.       result.put("code", SUCCESS);         
  28.       result.put("abilityResult", param.getFirstNum() + param.getSecondNum());         
  29.       // SYNC         
  30.       if (option.getFlags() == MessageOption.TF_SYNC) {           
  31.         reply.writeString(ZSONObject.toZSONString(result));         
  32.       } else {           
  33.       // ASYNC           
  34.         MessageParcel responseData = MessageParcel.obtain();           
  35.         responseData.writeString(ZSONObject.toZSONString(result));           
  36.         IRemoteObject remoteReply = reply.readRemoteObject();           
  37.         try {             
  38.           remoteReply.sendRequest(0, responseData, MessageParcel.obtain(), new MessageOption());           
  39.         } catch (RemoteException exception) { 
  40.           return false;           
  41.         } finally {               
  42.           responseData.reclaim();           
  43.         }         
  44.       }         
  45.       break;       
  46.     }       
  47.     default: {         
  48.       Map<String, Object> result = new HashMap<String, Object>();         
  49.       result.put("abilityError", ERROR);         
  50.       reply.writeString(ZSONObject.toZSONString(result));         
  51.       return false;       
  52.     }     
  53.   }     
  54.   return true;   
  55. }   
  56.  
  57. /**  * Internal ability 注冊接口。  */   
  58.   public static void register(AbilityContext abilityContext) {     
  59.     instance = new ComputeInternalAbility();     
  60.     instance.onRegister(abilityContext);   
  61.   }   
  62.   private void onRegister(AbilityContext abilityContext) {     
  63.     this.abilityContext = abilityContext;     
  64.     this.setInternalAbilityHandler((code, data, reply, option) -> {    
  65.     return this.onRemoteRequest(code, data, reply, option);     
  66.     });   
  67.   }   
  68. /**   * Internal ability 注銷接口。   */   
  69.   public static void unregister() {     
  70.     instance.onUnregister();   
  71.   }   
  72.   private void onUnregister() {     
  73.     abilityContext = null;     
  74.     this.setInternalAbilityHandler(null);   
  75.   } 

以上代碼樣例只是關(guān)鍵部分,完整代碼樣例可參考官網(wǎng)資料【JS FA如何調(diào)用PA】:

JS FA如何調(diào)用PA

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-js-fa-call-pa-0000001050435961

本文介紹了JS FA(Feature Ability)調(diào)用JAVA PA(Particle Ability)的機(jī)制和使用場景,基于JS UI框架開發(fā)的應(yīng)用可以使用該機(jī)制完成更豐富的功能。未來HarmonyOS會持續(xù)豐富完善JS API,為開發(fā)者提供更便捷的API能力。

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2021-10-27 10:05:55

鴻蒙HarmonyOS應(yīng)用

2021-09-10 15:13:41

鴻蒙HarmonyOS應(yīng)用

2022-03-07 14:58:10

ArkUIJS FAJava

2021-10-14 09:53:38

鴻蒙HarmonyOS應(yīng)用

2022-06-02 14:27:05

UI框架JS

2022-09-08 15:18:51

Ability鴻蒙

2015-08-17 09:46:15

UIjs

2021-12-20 10:07:39

鴻蒙HarmonyOS應(yīng)用

2022-11-11 10:56:37

2022-05-16 11:17:01

應(yīng)用開發(fā)JSJAVA

2020-02-20 15:19:56

JavaSQL注入

2014-07-21 17:48:09

PhoneGapCordovaHtml5

2009-06-01 10:47:32

jboss seam例jboss seam開jboss seam

2022-10-27 16:01:41

AbilityStage模型FA模型

2025-01-15 13:46:23

2011-09-08 10:32:27

Node.js

2011-07-01 11:02:30

EnyowebOShello world

2021-03-25 15:54:14

鴻蒙HarmonyOS應(yīng)用開發(fā)

2011-04-22 11:24:13

mootools

2024-11-26 07:40:44

3D游戲場景
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號