這一篇我們繼續(xù)深入一點(diǎn)點(diǎn),嘗試打通從用戶態(tài)UI到內(nèi)核態(tài)HDF之間的聯(lián)系。其中涉及到的調(diào)用關(guān)系比較復(fù)雜,建議在“用鴻蒙開發(fā)AI應(yīng)用(五)HDF 驅(qū)動(dòng)補(bǔ)光燈”的基礎(chǔ)上閱讀本文,HDF的相關(guān)細(xì)節(jié)這里就不在贅述了。
背景知識(shí)
用戶程序框架子系統(tǒng)包含兩個(gè)大的模塊:Ability子系統(tǒng)和包管理子系統(tǒng)。
1. Ability子系統(tǒng)

1.1 Ability
Ability是系統(tǒng)調(diào)度應(yīng)用的最小單元,是能夠完成一個(gè)獨(dú)立功能的組件,一個(gè)應(yīng)用可以包含一個(gè)或多個(gè)Ability。Ability分為兩種類型:Page類型的Ability和Service類型的Ability
Page類型的Ability:帶有界面,為用戶提供人機(jī)交互的能力。
Service類型的Ability:不帶界面,為用戶提供后臺(tái)任務(wù)機(jī)制。
1.2 AbilitySlice
AbilitySlice是單個(gè)頁面及其控制邏輯的總和,是Page類型Ability特有的組件,一個(gè)Page類型的Ability可以包含多個(gè)AbilitySlice,此時(shí),這些頁面提供的業(yè)務(wù)能力應(yīng)當(dāng)是高度相關(guān)的。

1.3 生命周期
生命周期是Ability被調(diào)度到啟動(dòng)、激活、隱藏和退出等各個(gè)狀態(tài)的的統(tǒng)稱。

Ability生命周期各狀態(tài)解析:
UNINITIALIZED:未初始狀態(tài),為臨時(shí)狀態(tài),Ability被創(chuàng)建后會(huì)由UNINITIALIZED狀態(tài)進(jìn)入INITIAL狀態(tài);
INITIAL:初始化狀態(tài),也表示停止?fàn)顟B(tài),表示當(dāng)前Ability未運(yùn)行,調(diào)用Start后進(jìn)入INACTIVE,同時(shí)回調(diào)開發(fā)者的OnStart生命周期回調(diào);
INACTIVE:未激活狀態(tài),表示當(dāng)前窗口已顯示但是無焦點(diǎn)狀態(tài),由于Window暫未支持焦點(diǎn)的概念,當(dāng)前狀態(tài)與ACTIVE一致。
ACTIVE:前臺(tái)激活狀態(tài),表示當(dāng)前窗口已顯示,并獲取焦點(diǎn),Ability在退到后臺(tái)之前先由ACTIVE狀態(tài)進(jìn)入INACTIVE狀態(tài);
BACKGROUND: 后臺(tái)狀態(tài),表示當(dāng)前Ability退到后臺(tái),Ability在被銷毀后由BACKGROUND狀態(tài)進(jìn)入INITIAL狀態(tài),或者重新被激活后由BACKGROUND狀態(tài)進(jìn)入ACTIVE狀態(tài)。
1.4 AbilityLoader
AbilityLoader負(fù)責(zé)注冊和加載開發(fā)者Ability的模塊。開發(fā)者開發(fā)的Ability先要調(diào)用AbilityLoader的注冊接口注冊到框架中,接著Ability啟動(dòng)時(shí)會(huì)被實(shí)例化。
1.5 AbilityManager
AbilityManager負(fù)責(zé)AbilityKit和Ability管理服務(wù)進(jìn)行IPC的通信。
1.6 EventHandler
EventHandler是AbilityKit提供給開發(fā)者的用于在Ability中實(shí)現(xiàn)線程間通信的一個(gè)模塊。
1.7 Ability運(yùn)行管理服務(wù)
Ability運(yùn)行管理服務(wù)是用于協(xié)調(diào)各Ability運(yùn)行關(guān)系、及生命周期進(jìn)行調(diào)度的系統(tǒng)服務(wù)。
其中,服務(wù)啟動(dòng)模塊負(fù)責(zé)Ability管理服務(wù)的啟動(dòng)、注冊等。
服務(wù)接口管理模塊負(fù)責(zé)Ability管理服務(wù)對外能力的管理。
進(jìn)程管理模塊負(fù)責(zé)Ability應(yīng)用所在進(jìn)程的啟動(dòng)和銷毀、及其進(jìn)程信息維護(hù)等功能。Ability棧管理模塊負(fù)責(zé)維護(hù)各個(gè)Ability之間跳轉(zhuǎn)的先后關(guān)系。
生命周期調(diào)度模塊是Ability管理服務(wù)根據(jù)系統(tǒng)當(dāng)前的操作調(diào)度Ability進(jìn)入相應(yīng)的狀態(tài)的模塊。
連接管理模塊是Ability管理服務(wù)對Service類型Ability連接管理的模塊。
1.8 AppSpawn
AppSpawn是負(fù)責(zé)創(chuàng)建Ability應(yīng)用所在進(jìn)程的系統(tǒng)服務(wù),該服務(wù)有較高的權(quán)限,為Ability應(yīng)用設(shè)置相應(yīng)的權(quán)限,并預(yù)加載一些通用的模塊,加速應(yīng)用的啟動(dòng)。
2. 包管理子系統(tǒng)
包管理子系統(tǒng),是OpenHarmony為開發(fā)者提供的安裝包管理框架。

BundleKit:是包管理服務(wù)對外提供的接口,有安裝/卸載接口、包信息查詢接口、包狀態(tài)變化監(jiān)聽接口。
包掃描器:用來解析本地預(yù)制或者安裝的安裝包,提取里面的各種信息,供管理子模塊進(jìn)行管理,持久化。
包安裝子模塊:安裝,卸載,升級(jí)一個(gè)包;包安裝服務(wù)一個(gè)單獨(dú)進(jìn)程的用于創(chuàng)建刪除安裝目錄,具有較高的權(quán)限。
包管理子模塊:管理安裝包相關(guān)的信息,存儲(chǔ)持久化包信息。
包安全管理子模塊:簽名檢查、權(quán)限授予、權(quán)限管理。
HDF驅(qū)動(dòng)LED(可選)
之前在內(nèi)核中已經(jīng)注冊過一個(gè)led_driver驅(qū)動(dòng),并以led_service服務(wù)發(fā)布,這一節(jié)稍微重構(gòu)一下代碼,功能上沒有變化,我們快速過一遍,熟悉HDF的可以自行跳過。
1. 業(yè)務(wù)代碼
先新建頭文件vendorhuaweihdfledincludeled_ctrl.h。
#ifndef _LED_CTRL_H #define _LED_CTRL_H #include "hdf_device_desc.h" #include "hdf_log.h" #include "device_resource_if.h" #include "osal_io.h" #include "osal_mem.h" #include "gpio_if.h" #include "osal_irq.h" #include "osal_time.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int32_t CtlLED(int mode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _LED_CTRL_H */
再新建源文件 vendorhuaweihdfledled_ctrl.c
#include "led_ctrl.h" #define HDF_LOG_TAG led_driver // 打印日志所包含的標(biāo)簽,如果不定義則用默認(rèn)定義的HDF_TAG標(biāo)簽 int32_t CtlLED(int mode) { int32_t ret; uint16_t valRead; /* LED的GPIO管腳號(hào) */ // uint16_t gpio = 5 * 8 + 1; // 紅外補(bǔ)光燈 uint16_t gpio = 2 * 8 + 3; // 綠色指示燈 // uint16_t gpio = 3 * 8 + 4; // 紅色指示燈 /* 將GPIO管腳配置為輸出 */ ret = GpioSetDir(gpio, GPIO_DIR_OUT); if (ret != 0) { HDF_LOGE("GpioSerDir: failed, ret %d ", ret); return ret; } if (mode == -1) { // 翻轉(zhuǎn)輸出口 (void)GpioRead(gpio, &valRead); ret = GpioWrite(gpio, (valRead == GPIO_VAL_LOW) ? GPIO_VAL_HIGH : GPIO_VAL_LOW); } else { ret = GpioWrite(gpio, mode); } if (ret != 0) { HDF_LOGE("GpioWrite: failed, ret %d ", ret); return ret; } return ret; }
先完成對綠色指示燈的控制邏輯。
2. 驅(qū)動(dòng)實(shí)現(xiàn) 在 huawei/hdf 目錄下新建一個(gè)文件夾 led, 然后在其中新建一個(gè)源文件 led.c。
#include "hdf_device_desc.h" // HDF框架對驅(qū)動(dòng)開放相關(guān)能力接口的頭文件 #include "hdf_log.h" // HDF 框架提供的日志接口頭文件 #include "led_ctrl.h" // #define HDF_LOG_TAG led_driver // 打印日志所包含的標(biāo)簽,如果不定義則用默認(rèn)定義的HDF_TAG標(biāo)簽 #define LED_WRITE_READ 1 // 讀寫操作碼1 // Dispatch是用來處理用戶態(tài)發(fā)下來的消息 int32_t LedDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t result = HDF_FAILURE; HDF_LOGE("Led driver dispatch"); if (client == NULL || client->device == NULL) { HDF_LOGE("Led driver device is NULL"); return HDF_ERR_INVALID_OBJECT; } switch (cmdCode) { case LED_WRITE_READ: const char *recv = HdfSbufReadString(data); if (recv != NULL) { HDF_LOGI("recv: %s", recv); result = CtlLED(-1); // result = CtlLED(GPIO_VAL_HIGH); if (!HdfSbufWriteInt32(reply, result)) { HDF_LOGE("replay is fail"); } return HdfDeviceSendEvent(client->device, cmdCode, data); } break; default: break; } return result; } //驅(qū)動(dòng)對外提供的服務(wù)能力,將相關(guān)的服務(wù)接口綁定到HDF框架 int32_t HdfLedDriverBind(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("Led driver bind failed!"); return HDF_ERR_INVALID_OBJECT; } static struct IDeviceIoService ledDriver = { .Dispatch = LedDriverDispatch, }; deviceObject->service = (struct IDeviceIoService *)(&ledDriver); HDF_LOGD("Led driver bind success"); return HDF_SUCCESS; } // 驅(qū)動(dòng)自身業(yè)務(wù)初始的接口 int32_t HdfLedDriverInit(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("Led driver Init failed!"); return HDF_ERR_INVALID_OBJECT; } HDF_LOGD("Led driver Init success"); return HDF_SUCCESS; } // 驅(qū)動(dòng)資源釋放的接口 void HdfLedDriverRelease(struct HdfDeviceObject *deviceObject) { if (deviceObject == NULL) { HDF_LOGE("Led driver release failed!"); return; } HDF_LOGD("Led driver release success"); return; } // 定義驅(qū)動(dòng)入口的對象,必須為HdfDriverEntry(在hdf_device_desc.h中定義)類型的全局變量 struct HdfDriverEntry g_ledDriverEntry = { .moduleVersion = 1, .moduleName = "led_driver", .Bind = HdfLedDriverBind, .Init = HdfLedDriverInit, .Release = HdfLedDriverRelease, }; // 調(diào)用HDF_INIT將驅(qū)動(dòng)入口注冊到HDF框架中,在加載驅(qū)動(dòng)時(shí)HDF框架會(huì)先調(diào)用Bind函數(shù),再調(diào)用Init函數(shù)加載該驅(qū)動(dòng),當(dāng)Init調(diào)用異常時(shí),HDF框架會(huì)調(diào)用Release釋放驅(qū)動(dòng)資源并退出。 HDF_INIT(g_ledDriverEntry);
3. 驅(qū)動(dòng)編譯 在 huawei/hdf/led 目錄下新建編譯文件 Makefile。
include $(LITEOSTOPDIR)/../../drivers/hdf/lite/lite.mk MODULE_NAME := hdf_led_driver LOCAL_SRCS += led_ctrl.c led.c LOCAL_INCLUDE := ./include LOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror include $(HDF_DRIVER)
4. 編譯結(jié)果鏈接到內(nèi)核鏡像 修改 huawei/hdf/hdf_vendor.mk 文件,添加以下代碼
LITEOS_BASELIB += -lhdf_led_driver #鏈接生成的靜態(tài)庫 LIB_SUBDIRS += $(VENDOR_HDF_DRIVERS_ROOT)/led #驅(qū)動(dòng)代碼Makefile的目錄
5. 驅(qū)動(dòng)配置 修改 vendor/hisi/hi35xx/hi3516dv300/config/device_info/device_info.hcs配置文件,添加驅(qū)動(dòng)的設(shè)備描述。
platform :: host {
hostName = "platform_host"; // host名稱,host節(jié)點(diǎn)是用來存放某一類驅(qū)動(dòng)的容器
priority = 50; // host啟動(dòng)優(yōu)先級(jí)(0-200),值越大優(yōu)先級(jí)越低,建議默認(rèn)配100,優(yōu)先級(jí)相同則不保證host的加載順序
device_led :: device { // led設(shè)備節(jié)點(diǎn)
device0 :: deviceNode { // led驅(qū)動(dòng)的DeviceNode節(jié)點(diǎn)
policy = 2; // policy字段是驅(qū)動(dòng)服務(wù)發(fā)布的策略,在驅(qū)動(dòng)服務(wù)管理章節(jié)有詳細(xì)介紹
priority = 100; // 驅(qū)動(dòng)啟動(dòng)優(yōu)先級(jí)(0-200),值越大優(yōu)先級(jí)越低,建議默認(rèn)配100,優(yōu)先級(jí)相同則不保證device的加載順序
preload = 0; // 驅(qū)動(dòng)按需加載字段
permission = 0666; // 驅(qū)動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)權(quán)限
moduleName = "led_driver"; // 驅(qū)動(dòng)名稱,該字段的值必須和驅(qū)動(dòng)入口結(jié)構(gòu)的moduleName值一致
serviceName = "led_service"; // 驅(qū)動(dòng)對外發(fā)布服務(wù)的名稱,必須唯一
deviceMatchAttr = "led_config"; // 驅(qū)動(dòng)私有數(shù)據(jù)匹配的關(guān)鍵字,必須和驅(qū)動(dòng)私有數(shù)據(jù)配置表中的match_attr值相等
}
}
編譯用戶程序框架子系統(tǒng) 1. 添加配置文件 在 build/lite/platform/hi3516dv300_liteos_a/platform.json中的subsystems字段下面添加appexecfwk和aafwk。
{
"subsystem": "aafwk",
"components": [
{
"component": "ability",
"optional": "true",
"dirs": [
"foundation/aafwk"
],
"targets": [
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilitykit_lite",
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilityMain_lite",
"http://foundation/aafwk/frameworks/abilitymgr_lite:aafwk_abilityManager_lite",
"http://foundation/aafwk/services/abilitymgr_lite:aafwk_services_lite"
],
"features": [
{"enable_ohos_appexecfwk_feature_ability": "true"}
],
"deps": {
"components": [
"hilog_a",
"bundle_mgr",
"system_ability_manager",
"distributed_schedule",
"graphic",
"utils",
"ipc"
],
"third_party": [
"cjson",
"bounds_checking_function"
]
}
}
]
},
{
"subsystem": "appexecfwk",
"components": [
{
"component": "bundle_mgr",
"optional": "true",
"dirs": [
"foundation/appexecfwk"
],
"targets": [
"http://foundation/appexecfwk/services/bundlemgr_lite:appexecfwk_services_lite",
"http://foundation/appexecfwk/frameworks/bundle_lite:appexecfwk_kits_lite"
],
"features": [],
"deps": {
"components": [
"iam",
"app_verify",
"hilog_a",
"system_ability_manager",
"global_resource_manager",
"graphic",
"utils"
],
"third_party": [
"cjson",
"zlib"
]
}
}
]
},
2. 添加編譯文件 新建buildliteconfigsubsystemaafwkBUILD.gn文件,
import("http://build/lite/config/subsystem/lite_subsystem.gni")
lite_subsystem("aafwk") {
subsystem_components = [
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilitykit_lite",
"http://foundation/aafwk/frameworks/abilitymgr_lite:aafwk_abilityManager_lite",
"http://foundation/aafwk/services/abilitymgr_lite:aafwk_services_lite",
]
}
新建/build/lite/config/subsystem/appexecfwk/BUILD.gn文件,
import("http://build/lite/config/subsystem/lite_subsystem.gni")
lite_subsystem("appexecfwk") {
subsystem_components = [
"http://foundation/appexecfwk/kits/appkit_lite:appexecfwk_kit_lite",
"http://foundation/appexecfwk/services/bundlemgr_lite:appexecfwk_services_lite",
]
}
3. 運(yùn)行管理服務(wù) 用戶程序框架有兩個(gè)系統(tǒng)服務(wù)ability管理服務(wù)(abilityms)和(bundlems),兩系統(tǒng)服務(wù)運(yùn)行于foundation進(jìn)程中。
abilityms和bundlems注冊到sa_manager中,sa_manager運(yùn)行于foundation進(jìn)程中,sa_manager為abilityms和bundlems創(chuàng)建線程運(yùn)行環(huán)境。
在foundation/distributedschedule/services/safwk_lite/BUILD.gn中添加對abilityms和bundlems
deps = [
"...",
]
if (ohos_kernel_type == "liteos_a") {
deps += [
"...",
"http://foundation/aafwk/services/abilitymgr_lite:abilityms",
"http://foundation/appexecfwk/services/bundlemgr_lite:bundlems",
"...",
]
}
基于AbilityKit開發(fā)的Ability 1. 主頁面實(shí)現(xiàn) 新建源文件applicationssamplecameramyLedAppsrcmain_ability.cpp
#include "main_ability.h"
namespace OHOS {
REGISTER_AA(MainAbility)
void MainAbility::OnStart(const Want &want)
{
printf("MainAbility::OnStart
");
SetMainRoute("MainAbilitySlice");
Ability::OnStart(want);
}
2. 分片頁面 2.1 定義控件常量 新建源文件main_ability_slice.cpp, 屏幕大小為960x480
#include "main_ability_slice.h"
#include "ability_manager.h"
#include "components/ui_label.h"
#include "components/ui_label_button.h"
namespace OHOS
{
REGISTER_AS(MainAbilitySlice)
constexpr static int BUTTON1_POSITION_X = 380;
constexpr static int BUTTON1_POSITION_Y = 200;
constexpr static int BUTTON_WIDTH = 200;
constexpr static int BUTTON_HEIGHT = 80;
constexpr static int ROOT_VIEW_POSITION_X = 0;
constexpr static int ROOT_VIEW_POSITION_Y = 0;
constexpr static int ROOT_VIEW_WIDTH = 960;
constexpr static int ROOT_VIEW_HEIGHT = 480;
constexpr static uint8_t ROOT_VIEW_OPACITY = 255;
constexpr static uint8_t FONT_ID = 10;
constexpr static int BUTTON1_POSITION_X = 380;
constexpr static int BUTTON1_POSITION_Y = 200;
constexpr static int BUTTON_WIDTH = 200;
constexpr static int BUTTON_HEIGHT = 80;
constexpr static int ROOT_VIEW_POSITION_X = 0;
constexpr static int ROOT_VIEW_POSITION_Y = 0;
constexpr static int ROOT_VIEW_WIDTH = 960;
constexpr static int ROOT_VIEW_HEIGHT = 480;
constexpr static uint8_t ROOT_VIEW_OPACITY = 255;
constexpr static uint8_t FONT_ID = 10;
} // namespace OHOS
2.2 創(chuàng)建按鈕和布局 在生命周期函數(shù)OnStart中,全屏放置一個(gè)rootView_,居中位置放置一個(gè)按鈕button1。
void MainAbilitySlice::OnStart(const Want &want)
{
printf("MainAbilitySlice::OnStart
");
AbilitySlice::OnStart(want);
auto button1 = new UILabelButton();
button1->SetPosition(BUTTON1_POSITION_X, BUTTON1_POSITION_Y);
button1->SetText("翻轉(zhuǎn) LED");
button1->Resize(BUTTON_WIDTH, BUTTON_HEIGHT);
button1->SetFontId(FONT_ID);
button1->SetStyle(STYLE_TEXT_COLOR, Color::Black().full);
button1->SetStyle(STYLE_TEXT_OPA, ROOT_VIEW_OPACITY);
button1->SetStyle(STYLE_BACKGROUND_OPA, ROOT_VIEW_OPACITY);
rootView_ = RootView::GetWindowRootView();
rootView_->SetPosition(ROOT_VIEW_POSITION_X, ROOT_VIEW_POSITION_Y);
rootView_->Resize(ROOT_VIEW_WIDTH, ROOT_VIEW_HEIGHT);
rootView_->Add(button1);
SetUIContent(rootView_);
}
2.3 實(shí)現(xiàn)驅(qū)動(dòng)消息機(jī)制 這里順便提一下,文檔中DevSvcManagerClntGetService接口僅在內(nèi)核態(tài)有效,可以方便的獲取服務(wù)并直接調(diào)用。鴻蒙作為微內(nèi)核的OS,想從用戶態(tài)調(diào)用內(nèi)核態(tài)函數(shù),要么用框架的消息機(jī)制,要么自己用中斷服務(wù)實(shí)現(xiàn)。
#define LED_WRITE_READ 1
#define LED_SERVICE "led_service"
static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
{
const char *string = HdfSbufReadString(data);
if (string == NULL)
{
printf("fail to read string in event data
");
return HDF_FAILURE;
}
printf("%s: dev event received: %u %s
", (char *)priv, id, string);
return HDF_SUCCESS;
}
static int SendEvent(struct HdfIoService *serv, const char *eventData)
{
int ret = 0;
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
if (data == NULL)
{
printf("fail to obtain sbuf data
");
return 1;
}
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
if (reply == NULL)
{
printf("fail to obtain sbuf reply
");
ret = HDF_DEV_ERR_NO_MEMORY;
HdfSBufRecycle(data);
return ret;
}
if (!HdfSbufWriteString(data, eventData))
{
printf("fail to write sbuf
");
ret = HDF_FAILURE;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
if (ret != HDF_SUCCESS)
{
printf("fail to send service call
");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
int replyData = 0;
if (!HdfSbufReadInt32(reply, &replyData))
{
printf("fail to get service call reply
");
ret = HDF_ERR_INVALID_OBJECT;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
printf("Get reply is: %d
", replyData);
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
2.4 加入點(diǎn)擊事件 每次點(diǎn)擊按鈕,向內(nèi)核態(tài)發(fā)送一次消息。
auto onClick = [this](UIView &view, const Event &event) -> bool {
printf("led button pressed
");
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE, 0);
if (serv == NULL)
{
printf("fail to get service %s
", LED_SERVICE);
return false;
}
static struct HdfDevEventlistener listener = {
.callBack = OnDevEventReceived,
.priv = (void *)"Service0"};
if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS)
{
printf("fail to register event listener
");
return false;
}
const char *send_cmd = "toggle LED";
if (SendEvent(serv, send_cmd))
{
printf("fail to send event
");
return false;
}
if (HdfDeviceUnregisterEventListener(serv, &listener))
{
printf("fail to unregister listener
");
return false;
}
HdfIoServiceRecycle(serv);
return true;
};
2.5 注銷頁面 在生命周期函數(shù)OnStop中,刪除所有節(jié)點(diǎn),回收系統(tǒng)資源。
void DeleteViewChildren(UIView *view)
{
if (view == nullptr) {
return;
}
while (view != nullptr) {
UIView *tempView = view;
view = view->GetNextSibling();
if (tempView->IsViewGroup()) {
DeleteViewChildren(dynamic_cast(tempView)->GetChildrenHead());
}
if (tempView->GetParent()) {
dynamic_cast(tempView->GetParent())->Remove(tempView);
}
delete tempView;
}
}
void MainAbilitySlice::OnStop()
{
printf("MainAbilitySlice::OnStop
");
AbilitySlice::OnStop();
DeleteViewChildren(rootView_);
}
3. 編譯配置 新增 applicationssamplecameramyLedAppBUILD.gn文件
import("http://build/lite/config/component/lite_component.gni")
import("http://build/lite/config/subsystem/aafwk/config.gni")
HDF_FRAMEWORKS = "http://drivers/hdf/frameworks"
src_path = "http://applications/sample/camera/myLedApp/src"
lite_library("ledability") {
target_type = "shared_library"
ldflags = [
"-shared",
]
sources = [
"${src_path}/main_ability.cpp",
"${src_path}/main_ability_slice.cpp",
]
include_dirs = [
".",
"http://foundation/aafwk/frameworks/ability_lite/example/entry/src/main/cpp",
"http://foundation/aafwk/interfaces/innerkits/abilitymgr_lite",
"http://foundation/aafwk/interfaces/kits/ability_lite",
"http://foundation/aafwk/interfaces/kits/want_lite",
"http://foundation/appexecfwk/interfaces/kits/bundle_lite",
"http://foundation/appexecfwk/utils/bundle_lite",
"http://foundation/communication/interfaces/kits/ipc_lite",
"http://foundation/graphic/lite/interfaces/kits/config",
"http://foundation/graphic/lite/interfaces/kits/ui",
"http://foundation/graphic/lite/interfaces/kits/utils",
"http://kernel/liteos_a/kernel/common",
"http://kernel/liteos_a/kernel/include",
"http://drivers/hdf/lite/include/host",
"$HDF_FRAMEWORKS/ability/sbuf/include",
"$HDF_FRAMEWORKS/core/shared/include",
"$HDF_FRAMEWORKS/core/host/include",
"$HDF_FRAMEWORKS/core/master/include",
"$HDF_FRAMEWORKS/include/core",
"$HDF_FRAMEWORKS/include/utils",
"$HDF_FRAMEWORKS/utils/include",
"$HDF_FRAMEWORKS/include/osal",
"http://kernel/liteos_a/platform/include",
"$HDF_FRAMEWORKS/adapter/syscall/include",
"$HDF_FRAMEWORKS/adapter/vnode/include",
]
deps = [
"http://foundation/aafwk/frameworks/ability_lite:aafwk_abilitykit_lite",
"http://drivers/hdf/lite/manager:hdf_core",
"http://drivers/hdf/lite/adapter/osal/posix:hdf_posix_osal",
]
defines = [
"OHOS_APPEXECFWK_BMS_BUNDLEMANAGER",
]
if (enable_ohos_appexecfwk_feature_ability == true) {
deps += [
"http://foundation/graphic/lite/frameworks/ui:ui",
]
defines += [
"ENABLE_WINDOW=1",
"ABILITY_WINDOW_SUPPORT"
]
}
output_dir = "$root_out_dir/dev_tools/led"
}
4. 應(yīng)用配置文件 新建 applicationssamplecameramyLedAppconfig.json
{
"app": {
"bundleName": "com.bluishfish.ledability",
"vendor": "huawei",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 3,
"target": 3
}
},
"deviceConfig": {
"default": {
"keepAlive": false
}
},
"module": {
"deviceType": [
"smartVision"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "ledability",
"moduleType": "entry"
},
"abilities": [{
"name": "MainAbility",
"icon": "assets/entry/resources/base/media/icon.png",
"label": "Led Ability",
"launchType": "standard",
"type": "page",
"visible": true
}
]
}
}

5. 板級(jí)編譯配置 復(fù)制 build/lite/product/ipcamera_hi3516dv300.json,改名為my_hi3516dv300在子系統(tǒng)里加入
{
"ohos_version": "OpenHarmony 1.0",
"board": "hi3516dv300",
"kernel": "liteos_a",
"compiler": "clang",
"subsystem": [
{
"name": "aafwk",
"component": [
"......",
{ "name": "ability_led", "dir": "http://applications/sample/camera/myLedApp:ledability", "features": []}
]
"......"
6. 編譯應(yīng)用
python build.py my_hi3516dv300 -b debug

將系統(tǒng)燒錄到開發(fā)板上。
7. 打包應(yīng)用 在 assetsentry esourcesasemedia目錄下放置一個(gè)icon.png作為啟動(dòng)圖標(biāo)。
將applicationssamplecameramyLedAppconfig.json和 Z:openharmonyoutmy_hi3516dv300dev_toolsledlibledability.so打包壓縮成zip包

改名為ledability.hap ,復(fù)制到NFS共享目錄
8. 安裝Hap
mkdir nfs mount 192.168.1.57:/nfs /nfs nfs ./nfs/dev_tools/bin/bm set -s disable ./nfs/dev_tools/bin/bm install -p ./nfs/ledability.hap

9. 運(yùn)行程序
./nfs/dev_tools/bin/aa start -p com.bluishfish.ledability -n MainAbility
完美!
-
AI
+關(guān)注
關(guān)注
91文章
39083瀏覽量
299635 -
鴻蒙系統(tǒng)
+關(guān)注
關(guān)注
183文章
2642瀏覽量
69597
發(fā)布評論請先 登錄
觸摸屏的工作原理
觸摸屏的應(yīng)用與工作原理
電阻式觸摸屏,什么是電阻式觸摸屏
基于單片機(jī)的液晶顯示觸摸屏控制設(shè)計(jì)
觸摸屏技術(shù)是誰發(fā)明的_觸摸屏技術(shù)的發(fā)展歷程
基于觸摸屏控制的LED彩色臺(tái)燈控制系統(tǒng)的設(shè)計(jì)
組態(tài)王和觸摸屏哪個(gè)好_組態(tài)王和觸摸屏區(qū)別
基于觸摸屏的LED驅(qū)動(dòng)電路設(shè)計(jì)
PLC觸摸屏的作用_觸摸屏是怎樣控制PLC的
觸摸屏電容屏原理_觸摸屏有哪些應(yīng)用領(lǐng)域
觸摸屏電容屏的原理,觸摸屏有哪些應(yīng)用領(lǐng)域
modbus觸摸屏
基于鴻蒙開發(fā)的觸摸屏控制LED
評論