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

OpenHarmony 源碼解析之JavaScript API框架(NAPI)

開發(fā) 前端
JavaScript Application Programming Interface, JavaScript應(yīng)用程序編程接口。OpenHarmony上JS API實現(xiàn)方式有三種,分別是:JSI機(jī)制、Channel機(jī)制、NAPI機(jī)制。

[[424375]]

想了解更多內(nèi)容,請訪問:

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

https://harmonyos.51cto.com

1.NAPI概念

1.1 JS API概念

JS API: JavaScript Application Programming Interface, JavaScript應(yīng)用程序編程接口。

1.2 JS API實現(xiàn)方式

OpenHarmony上JS API實現(xiàn)方式有三種,分別是:JSI機(jī)制、Channel機(jī)制、NAPI機(jī)制。

JSI機(jī)制:L0~L1設(shè)備支持。

Channel機(jī)制:L3設(shè)備支持。

NAPI機(jī)制:目前僅L2設(shè)備支持,后續(xù)須推廣到L3~L5設(shè)備。

OpenHarmony 源碼解析之JavaScript API框架(NAPI)-鴻蒙HarmonyOS技術(shù)社區(qū)

1.3 NAPI概念

一句話概括NAPI,就是L2設(shè)備上的 JS API實現(xiàn)方式。

2.NAPI機(jī)制介紹

2.1 實現(xiàn)原則

優(yōu)先封裝異步方法!同步方法可待社區(qū)反饋需要時再行添加。

若引擎開啟Promise特性支持,則異步方法必須同時支持Callback方式和Promise方式。使用哪種方式由應(yīng)用開發(fā)者決定,以是否傳遞Callback進(jìn)行區(qū)分。不傳遞Callback即為Promise方式,方法執(zhí)行結(jié)果為Promise實例對象。

  • L0到L1設(shè)備上受限于硬件水平,只實現(xiàn)Callback方式的異步方法;
  • L2到L5設(shè)備上,必須實現(xiàn)同時支持Callback方式和Promise方式的異步方法。

2.2 異步編程模型

2.2.1Promise 異步模型

Promise 異步模型是 OHOS 標(biāo)準(zhǔn)異步模型之一。

Promise對象: ES6原生提供了Promise對象,Promise是異步編程的一種解決方案,可以替代傳統(tǒng)的解決方案–回調(diào)函數(shù)和事件。promise對象是一個異步操作的結(jié)果,提供了一些API使得異步執(zhí)行可以按照同步的流表示出來,避免了層層嵌套的回調(diào)函數(shù),保證了回調(diào)是以異步的方式進(jìn)行調(diào)用的。用戶在調(diào)用這些接口的時候,接口實現(xiàn)將異步執(zhí)行任務(wù),同時返回一個 Promise 對象,其代表異步操作的結(jié)果。在返回的結(jié)果的個數(shù)超過一個時,其以對象屬性的形式返回。

Promise特點 作為對象,Promise有兩個特點:(1)對象的狀態(tài)不受外界影響;(2)一旦狀態(tài)改變了就不會再變,也就是說任何時候Promise都只有一種狀態(tài)。

2.2.2Callback 異步模型

Callback 異步模型是 OHOS 標(biāo)準(zhǔn)異步模型之一。用戶在調(diào)用這些接口的時候,接口實現(xiàn)將異步執(zhí)行任務(wù)。任務(wù)執(zhí)行結(jié)果以參數(shù)的形式提供給用戶注冊的回調(diào)函數(shù)。這些參數(shù)的第一個是 Error 或 undefined 類型,分別表示執(zhí)行出錯與正常。

2.2 實現(xiàn)步驟

2.2.1 模塊注冊

API集合按業(yè)務(wù)功能進(jìn)行模塊劃分。開發(fā)者使用前須import對應(yīng)的模塊。

命名:@ohos.模塊名

注意:

  • 模塊名須唯一,由ACE團(tuán)隊統(tǒng)一維護(hù),子系統(tǒng)新增模塊時須向ACE團(tuán)隊申請。
  • 模塊名最好是單個名詞。實在不行,也可以由多個名詞組成,但必須遵循小駝峰命名規(guī)則。
  • 一個模塊,一個聲明文件(*.d.ts)。聲明文件命名遵循@ohos.模塊名.d.ts,文件名全小寫,單詞間無分割。

N-API通過注冊函數(shù)進(jìn)行模塊的注冊,其接受一個全局變量參數(shù),全局變量結(jié)構(gòu)體中定義了模塊名及模塊初始化函數(shù)。在模塊的初始化中,我們可以定義模塊需要暴露的方法及屬性。

示例:

  1. static napi_value StorageExport(napi_env env, napi_value exports) 
  2.  
  3. const char* storageClassName = "Storage"
  4. napi_value storageClass = nullptr; 
  5.  
  6. /* 定義模塊需要對外暴露的方法 */ 
  7. static napi_property_descriptor storageDesc[] = { 
  8.     DECLARE_NAPI_FUNCTION("get", JSStorageGet), 
  9.     DECLARE_NAPI_FUNCTION("getSync", JSStorageGetSync), 
  10. }; 
  11.  
  12. /* 定義C++類對應(yīng)的JavaScript類,包括JS類名、JS構(gòu)造函數(shù) */ 
  13. napi_define_class(env, storageClassName, strlen(storageClassName), JSStorageConstructor, nullptr, 
  14.                   sizeof(storageDesc) / sizeof(storageDesc[0]), storageDesc, &storageClass); 
  15.  
  16. /* 定義模塊需要對外暴露的屬性 */ 
  17. static napi_property_descriptor desc[] = { 
  18.     DECLARE_NAPI_PROPERTY("Storage", storageClass), 
  19. }; 
  20.  
  21. /* 設(shè)置exports對象屬性 */ 
  22. napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 
  23. return exports; 

模塊定義

  1. static napi_module storageModule = { 
  2.     .nm_version = 1, 
  3.     .nm_flags = 0, 
  4.     .nm_filename = nullptr, 
  5.     .nm_register_func = StorageExport, 
  6.     .nm_modname = "storage"
  7.     .nm_priv = ((void*)0), 
  8.     .reserved = { 0 }, 
  9.     }; 

 模塊注冊

  1. extern "C" __attribute__((constructor)) void StorageRegister() 
  2.     napi_module_register(&storageModule); 

2.2.2 NAPI聲明

聲明文件模板

@ohos.模塊名.d.ts文件:

  1. /** 
  2. * 模塊描述 
  3. * @since API版本號,IT Release3 對應(yīng) 4,以此類推 
  4. * @sysCap 系統(tǒng)能力 
  5. * @devices 支持設(shè)備 
  6. * @import 導(dǎo)入模塊 
  7. * @permission 權(quán)限列表 
  8. */ 
  9. declare namespace 模塊名 { 
  10. // 在此處定義功能方法 
  11.  
  12. export default 模塊名; 

示例:

聲明文件@ohos.storage.d.ts

  1. /** 
  2.  * 存儲 
  3.  * @since 3 
  4.  * @sysCap ACE Engine 
  5.  * @devices phone, tablet, tv, wearable, liteWearable, smartVision 
  6.  * @import import storage from '@ohos.storage'
  7.  * @permission N/A 
  8.  */ 
  9. declare namespace storage { 
  10.   // 在此處定義功能方法 
  11.    
  12. export default storage; 

2.2.2 NAPI實現(xiàn)

JS API 調(diào)用流程如下圖所示:

OpenHarmony 源碼解析之JavaScript API框架(NAPI)-鴻蒙HarmonyOS技術(shù)社區(qū)

接口定義

  1.  /**入?yún)?*     
  2.   napi_env:表示一個上下文的變量;   
  3.   napi_callback_info:傳遞給回調(diào)函數(shù)的一個封裝的數(shù)據(jù)類型,可以用于獲取有關(guān)調(diào)用時的上下文信息,也可以用于設(shè)置回調(diào)函數(shù)的返回值; 
  4.  
  5.  **返回值**     
  6.  napi_value:對所有js的基本值的一個密閉封裝,就是表示一個基本值; 
  7.  */ 
  8.  
  9. static napi_value Get(napi_env env, napi_callback_info info); 
  10. static napi_value GetSync(napi_env env, napi_callback_info info); 

2.2.2.1 同步回調(diào)

同步方法調(diào)用之后,將阻塞住JS線程直至獲取到返回值。

命名:動詞+Sync或動詞+名詞+Sync

格式:

  • 無參:方法名()
  • 有參:方法名Sync(必填參數(shù)[, 可選參數(shù)])

返回值

聲明文件模板

  1. declare namespace 模塊名  
  2.    /** 
  3.    * 方法描述 
  4.    * @note 特殊說明 
  5.    * @since (可選,方法支持版本與模塊不一致時需標(biāo)明) 
  6.    * @sysCap 系統(tǒng)能力 
  7.    * @devices 支持設(shè)備 (可選,支持設(shè)備類型與模塊不一致時需標(biāo)明) 
  8.     * @param 參數(shù) 參數(shù)說明(可選,沒有參數(shù)或參數(shù)用interface包含時不需要標(biāo)明) 
  9.    * @return 返回值說明(可選,沒有返回值或返回值用interface包含時不需要標(biāo)明) 
  10.     */ 
  11.  
  12.    // 無參 
  13.    function 方法名Sync(): 返回值類型; 
  14.  
  15.     // 有參 
  16.     function 方法名Sync(必填參數(shù): 參數(shù)類型, options?: 可選參數(shù)類型): 返回值類型; 
  17.  
  18.     interface 可選參數(shù)類型 { 
  19.    參數(shù)名: 參數(shù)類型; 
  20.     } 
  21.  
  22. export default 模塊名; 

示例

聲明

  1. declare namespace storage { 
  2.   /** 
  3.    * getSync方法描述 
  4.    * @since 6 
  5.    * @sysCap ACE Enginge 
  6.    * @param key key值說明 
  7.    * @return 返回值說明 
  8.    */ 
  9.   function getSync(key: string,  options?: GetStorageOptions): string; 
  10.    
  11.   interface GetStorageOptions { 
  12.     /** 
  13.      * default參數(shù)描述 
  14.      * @since 6 
  15.      * @sysCap ACE Enginge 
  16.      */ 
  17.     default: string; 
  18.   } 
  19.    
  20. export default storage; 

實現(xiàn)

  1. static napi_value GetSync(napi_env env, napi_callback_info info)         
  2.         {        
  3.             size_t requireArgc = 1; 
  4.             size_t argc = 2; //參數(shù)個數(shù) 
  5.             napi_value argv[2] = { 0 }; //參數(shù)定義 
  6.             napi_value thisVar = nullptr; //JS對象的this參數(shù) 
  7.             void* data = nullptr; //回調(diào)數(shù)據(jù)指針 
  8.  
  9.             /* 根據(jù)環(huán)境變量獲取參數(shù) */ 
  10.             napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 
  11.              
  12.             NAPI_ASSERT(env, argc >= requireArgc, "requires 1 parameter"); 
  13.              
  14.             char key[KEY_BUFFER_SIZE] = { 0 }; 
  15.             size_t keyLen = 0; 
  16.             char value[VALUE_BUFFER_SIZE] = { 0 }; 
  17.             size_t valueLen = 0; 
  18.             for (size_t i = 0; i < argc; i++) { 
  19.                 napi_valuetype valueType = napi_undefined; 
  20.                 napi_typeof(env, argv[i], &valueType);   
  21.                 if (i == 0 && valueType == napi_string) { 
  22.  
  23.                     /* 根據(jù)JS字符串獲取對應(yīng)的UTF8編碼格式的C/C++字符串 */ 
  24.                     napi_get_value_string_utf8(env, argv[i], key, KEY_BUFFER_SIZE, &keyLen); 
  25.                 } else if (i == 1 && valueType == napi_string) { 
  26.                     napi_get_value_string_utf8(env, argv[i], value, VALUE_BUFFER_SIZE, &valueLen); 
  27.                     break; 
  28.                 } else { 
  29.                     NAPI_ASSERT(env, false"type mismatch"); 
  30.                 } 
  31.             } 
  32.             StorageObjectInfo* objectInfo = nullptr; 
  33.  
  34.             /* 根據(jù)JS對象獲取與之綁定的原生對象實例 */ 
  35.             napi_unwrap(env, thisVar, (void**)&objectInfo); 
  36.             auto itr = g_keyValueStorage.find(key); 
  37.             napi_value result = nullptr; // JS字符串對象 
  38.             if (itr != g_keyValueStorage.end()) { 
  39.                  
  40.                 /* 根據(jù)UTF8編碼格式的 C/C++字符串 創(chuàng)建一個 JS字符串對象 */ 
  41.                 napi_create_string_utf8(env, itr->second.c_str(), itr->second.length(), &result); 
  42.             } else if (valueLen > 0) { 
  43.                 napi_create_string_utf8(env, value, valueLen, &result); 
  44.             } else { 
  45.                 objectInfo->Emit(nullptr, "error"); 
  46.                 NAPI_ASSERT(env, false"key does not exist"); 
  47.             } 
  48.             return result; //返回JS對象 
  49.         } 

2.2.2.2 異步回調(diào)

異步方法調(diào)用整個過程不會阻礙調(diào)用者的工作。

命名:動詞或動詞+名詞

格式:

  • 無參:方法名([回調(diào)函數(shù)])
  • 有參:方法名(必填參數(shù)[, 可選參數(shù)][, 回調(diào)函數(shù)])

返回值

  • 若回調(diào)函數(shù)非空,則返回void
  • 若回調(diào)函數(shù)為空,則返回Promise實例對象

聲明文件模板

  1. declare namespace 模塊名 { 
  2.  
  3. /** 
  4. * 方法描述 
  5. * @note 特殊說明 
  6. * @since (可選,方法支持版本與模塊不一致時需標(biāo)明) 
  7. * @sysCap 系統(tǒng)能力 
  8. * @devices 支持設(shè)備 (可選,支持設(shè)備類型與模塊不一致時需標(biāo)明) 
  9. * @param 參數(shù) 參數(shù)說明(可選,沒有參數(shù)或參數(shù)用interface包含時不需要標(biāo)明) 
  10. */ 
  11.  
  12. // 無參 
  13. function 方法名(callback: AsyncCallback<結(jié)果數(shù)據(jù)類型>): void; 
  14. function 方法名(): Promise<結(jié)果數(shù)據(jù)類型>; 
  15.  
  16. // 有參 
  17. function 方法名(必填參數(shù): 參數(shù)類型, callback: AsyncCallback<結(jié)果數(shù)據(jù)類型>): void; 
  18. function 方法名(必填參數(shù): 參數(shù)類型, options: 可選參數(shù)類型, callback: AsyncCallback<結(jié)果數(shù)據(jù)類型>): void; 
  19. function 方法名(必填參數(shù): 參數(shù)類型, options?: 可選參數(shù)類型): Promise<結(jié)果數(shù)據(jù)類型>; 
  20.  
  21. interface 可選參數(shù)類型 { 
  22.  參數(shù)名: 參數(shù)類型; 
  23.  
  24. export default 模塊名; 

示例:

聲明

  1. import { AsyncCallback } from './basic'
  2.  
  3. declare namespace storage { 
  4. /** 
  5. * get方法描述 
  6. * @note N/A 
  7. * @since 5 
  8. * @sysCap ACE Engine 
  9. * @devices phone, tablet, tv, wearable 
  10. * @param key key值說明 
  11. */ 
  12. function get(key: string, callback: AsyncCallback<string>): void; 
  13. function get(key: string, options: GetStorageOptions, callback: AsyncCallback<string>): void; 
  14. function get(key: string, options?: GetStorageOptions): Promise<string>; 
  15.  
  16. interface GetStorageOptions { 
  17. default: string; 
  18.  
  19. export default storage; 

實現(xiàn)

異步回調(diào)流程如下圖所示:

OpenHarmony 源碼解析之JavaScript API框架(NAPI)-鴻蒙HarmonyOS技術(shù)社區(qū)
  1. static napi_value Get(napi_env env, napi_callback_info info) 
  2.     size_t requireArgc = 1; 
  3.     size_t argc = 3; //參數(shù)個數(shù) 
  4.     napi_value argv[3] = { 0 }; //參數(shù)定義 
  5.     napi_value thisVar = nullptr; //JS對象的this參數(shù) 
  6.     void* data = nullptr; //回調(diào)數(shù)據(jù)指針 
  7.  
  8.     /* 根據(jù)環(huán)境變量獲取參數(shù) */ 
  9.     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 
  10.  
  11.     NAPI_ASSERT(env, argc >= requireArgc, "requires 1 parameter"); 
  12.  
  13.     /* 異步接口上下文,用于接收J(rèn)S接口傳進(jìn)來的環(huán)境變量、參數(shù)、回調(diào)函數(shù)、接口返回值等*/ 
  14.     auto asyncContext = new StorageAsyncContext(); 
  15.  
  16.     asyncContext->env = env; 
  17.  
  18.     for (size_t i = 0; i < argc; i++) { 
  19.         napi_valuetype valueType = napi_undefined; 
  20.         napi_typeof(env, argv[i], &valueType); 
  21.  
  22.         if ((i == 0) && (valueType == napi_string)) { 
  23.  
  24.             /* 根據(jù)JS字符串獲取對應(yīng)的UTF8編碼格式的C/C++字符串 */ 
  25.             napi_get_value_string_utf8(env, argv[i], asyncContext->key, KEY_BUFFER_SIZE, &asyncContext->keyLen); 
  26.         } else if (valueType == napi_string) { 
  27.             napi_get_value_string_utf8(env, argv[i], asyncContext->value, VALUE_BUFFER_SIZE, &asyncContext->valueLen); 
  28.         } else if (valueType == napi_function) { 
  29.  
  30.             /* 根據(jù)JS對象參數(shù)argv[i]新建引用 */ 
  31.             napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); 
  32.             break; 
  33.         } else { 
  34.             NAPI_ASSERT(env, false"type mismatch"); 
  35.         } 
  36.     } 
  37.  
  38.     napi_value result = nullptr; 
  39.  
  40.     if (asyncContext->callbackRef == nullptr) { 
  41.  
  42.         /* Promise方式異步調(diào)用,創(chuàng)建延遲對象、JS Promise對象,使二者進(jìn)行關(guān)聯(lián) */ 
  43.         napi_create_promise(env, &asyncContext->deferred, &result); 
  44.     } else { 
  45.  
  46.         /* Callback方式異步調(diào)用,不需要返回Promise對象,返回一個JS未定義值 */ 
  47.         napi_get_undefined(env, &result); 
  48.     } 
  49.  
  50.     /* 根據(jù)JS對象獲取與之綁定的原生對象實例 */ 
  51.     napi_unwrap(env, thisVar, (void**)&asyncContext->objectInfo); 
  52.  
  53.     napi_value resource = nullptr; 
  54.     napi_create_string_utf8(env, "JSStorageGet", NAPI_AUTO_LENGTH, &resource); //獲取JS異步資源名稱 
  55.  
  56.     /* 創(chuàng)建異步工作 */ 
  57.     napi_create_async_work( 
  58.         env, nullptr, resource, 
  59.          
  60.         /* 執(zhí)行異步邏輯的原生函數(shù) */ 
  61.         [](napi_env env, void* data) { 
  62.             StorageAsyncContext* asyncContext = (StorageAsyncContext*)data; 
  63.             auto itr = g_keyValueStorage.find(asyncContext->key); 
  64.             if (itr != g_keyValueStorage.end()) { 
  65.                 if (strncpy_s(asyncContext->value, VALUE_BUFFER_SIZE, itr->second.c_str(), itr->second.length()) == 
  66.                     -1) { 
  67.                     asyncContext->status = 1; //失敗 
  68.                 } else { 
  69.                     asyncContext->status = 0; //成功 
  70.                 } 
  71.             } else { 
  72.                 asyncContext->status = 1; //失敗 
  73.             } 
  74.         }, 
  75.  
  76.         /* 異步函數(shù)執(zhí)行完成或者取消后,需要執(zhí)行的后處理函數(shù) */ 
  77.         [](napi_env env, napi_status status, void* data) { 
  78.             StorageAsyncContext* asyncContext = (StorageAsyncContext*)data; 
  79.             napi_value result[2] = { 0 }; 
  80.             if (!asyncContext->status) { 
  81.                 napi_get_undefined(env, &result[0]); 
  82.                 napi_create_string_utf8(env, asyncContext->value, strlen(asyncContext->value), &result[1]); 
  83.             } else { 
  84.                 napi_value message = nullptr; 
  85.                 napi_create_string_utf8(env, "key does not exist", NAPI_AUTO_LENGTH, &message); 
  86.                 napi_create_error(env, nullptr, message, &result[0]); 
  87.                 napi_get_undefined(env, &result[1]); 
  88.                 asyncContext->objectInfo->Emit(nullptr, "error"); 
  89.             } 
  90.             if (asyncContext->deferred) { 
  91.                 if (!asyncContext->status) { 
  92.  
  93.                     /* 異步函數(shù)執(zhí)行成功后,執(zhí)行成功后處理函數(shù) */ 
  94.                     napi_resolve_deferred(env, asyncContext->deferred, result[1]);  
  95.                 } else { 
  96.  
  97.                     /* 異步函數(shù)執(zhí)行失敗后,執(zhí)行失敗后處理函數(shù) */ 
  98.                     napi_reject_deferred(env, asyncContext->deferred, result[0]); 
  99.                 } 
  100.             } else { 
  101.                 napi_value callback = nullptr; 
  102.                 napi_get_reference_value(env, asyncContext->callbackRef, &callback); 
  103.                 napi_call_function(env, nullptr, callback, sizeof(result) / sizeof(result[0]), result, nullptr); 
  104.                 napi_delete_reference(env, asyncContext->callbackRef); 
  105.             } 
  106.  
  107.             /* 異步回調(diào)完成后進(jìn)行資源釋放 */ 
  108.             napi_delete_async_work(env, asyncContext->work); 
  109.             delete asyncContext; 
  110.         }, 
  111.  
  112.         /* 用戶數(shù)據(jù)上下文,此數(shù)據(jù)傳遞給異步執(zhí)行函數(shù)與后處理函數(shù) */ 
  113.         (void*)asyncContext, 
  114.  
  115.         /* 生成的異步工作*/ 
  116.          &asyncContext->work); 
  117.     napi_queue_async_work(env, asyncContext->work); //異步工作入隊列,排隊執(zhí)行 
  118.  
  119.     return result; 

3. 應(yīng)用代碼示例

JS應(yīng)用引用NAPI接口時,須先引用接口定義的對應(yīng)模塊,才能進(jìn)行接口的調(diào)用。

  1. import storage from '@ohos.storage' 
  2. export default {  
  3.  
  4.     testGetSync() { 
  5.         //同步接口   
  6.         var name = storage.getSync('name');          
  7.         console.log('name is ' + name);  
  8.     },  
  9.     testGet() {  
  10.         //異步接口 
  11.         storage.get('name') .then(date => console.log('name is ' + data) ) .catch(error => console.log('error: ' + error) );  
  12.     }  
  13. }  

想了解更多內(nèi)容,請訪問:

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

https://harmonyos.51cto.com

 

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

2022-07-19 20:04:31

NAPI模塊鴻蒙

2021-11-25 09:54:54

鴻蒙HarmonyOS應(yīng)用

2021-12-08 15:07:51

鴻蒙HarmonyOS應(yīng)用

2021-12-06 06:19:03

鴻蒙HarmonyOS應(yīng)用

2024-01-03 15:41:49

2021-08-30 18:09:57

鴻蒙HarmonyOS應(yīng)用

2022-02-14 14:47:11

SystemUIOpenHarmon鴻蒙

2022-05-17 10:42:36

reboot源碼解析

2022-06-13 14:18:39

電源管理子系統(tǒng)耗電量服務(wù)

2022-05-20 10:32:49

事件循環(huán)器事件隊列鴻蒙

2022-01-06 16:17:58

鴻蒙HarmonyOS應(yīng)用

2022-02-17 20:57:07

OpenHarmon操作系統(tǒng)鴻蒙

2021-09-18 14:40:37

鴻蒙HarmonyOS應(yīng)用

2021-11-08 15:04:47

鴻蒙HarmonyOS應(yīng)用

2022-07-05 16:03:29

電源管理子系統(tǒng)鴻蒙

2021-12-17 16:42:09

鴻蒙HarmonyOS應(yīng)用

2022-01-20 14:33:29

openharmonwayland協(xié)議鴻蒙

2022-01-10 15:30:11

鴻蒙HarmonyOS應(yīng)用

2023-04-12 15:31:11

系統(tǒng)服務(wù)管理鴻蒙

2023-03-17 07:53:20

K8sAPIServerKubernetes
點贊
收藏

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