【鴻蒙開發】建立第一個Feature

目錄:java

1.  建立Service變量ide

2. 建立Feature變量post

3. 註冊Service&Featureui

4. 添加初始化code

 

源碼裏是有Feature的示例的,但當本身寫一個本身的Feature時,卻遇到了各類問題,有些是示例代碼和文檔沒有說明的小坑,這裏記錄一下。因源碼裏的startup目錄沒有任何代碼,就選擇它來存放代碼。開發

1.  BUILD.gn文件裏的source_set("startup")須要修改爲 static_library("startup")。文檔

     source_set 應該是不會打包進去仍是什麼,代碼不會被執行,修改爲static_library發現bin文件也增大了一些。字符串

2.  使用SYSEX_FEATURE_INIT(Init);進行初始化便可,可不使用SYS_RUN()和CORE_INI()宏。get

3.  直接使用SAMGR_GetInstance()->RegisterFeature(),並不能啓動Feature。Feature的啓動須要配全Service一塊使用,在使用SAMGR_GetInstance()->RegisterFeature()前須要先SAMGR_GetInstance()->RegisterService()註冊一個同命的Service才行。這點是最坑的地址,註冊Feature時參數是Service名稱字符串,因此就很容易想到直接註冊就能夠了,結束事實證實這樣是行不通的。源碼

4.  頭文件的順序,#include <ohos_init.h>要在#include "hctest.h"以前,不然SYSEX_FEATURE_INIT引用的是hos_init.h裏的聲明,而不是ohos_init.h文件裏的聲明

下面看一下添加Feature的正確方式:

1.  建立Service變量

static const char *GetName(Service *service);
static BOOL Initialize(Service *service, Identity identity);
static BOOL MessageHandle(Service *service, Request *msg);
static TaskConfig GetTaskConfig(Service *service);
static Service g_exampleService={
    .GetName=GetName,
    .Initialize=Initialize,
    .MessageHandle=MessageHandle,
    .GetTaskConfig=GetTaskConfig
};

2. 建立Feature變量

      這裏定義Feature沒有直接使用Feature進行定義,而是使用了源碼示例中的另外一種方式,即同類型定義。

typedef struct DemoApi{
    INHERIT_IUNKNOWN;
    BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
    BOOL (*SyncCall)(IUnknown *iUnknown,struct Payload *payload);
} DemoApi;

typedef struct DemoFeature{
    INHERIT_FEATURE;
    INHERIT_IUNKNOWNENTRY(DemoApi);
    Identity identity;
} DemoFeature;

static BOOL AsyncCall(IUnknown *iUnknown, const char *body);
static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload);
static const char* FEATURE_GetName(Feature *feature);
static void FEATURE_OnInitialize(Feature *feature, Service* parent, Identity identity);
static void FEATURE_OnStop(Feature *feature, Identity identity);
static BOOL FEATURE_OnMessage(Feature *feature, Request *request);

3. 註冊Service&Feature

SAMGR_GetInstance()->RegisterService(&g_exampleService);
SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE,(Feature*)&g_example);
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE,EXAMPLE_FEATURE,GET_IUNKNOWN(g_example));

4. 添加初始化

SYSEX_FEATURE_INIT(Init);

作完以上步驟後編譯燒寫到wifi-iot開發板後就能夠看到Feature能被正常初始化了。固然上面只是貼出了核心代碼,聲明的方法仍是須要再實現一下的,下面是完整的代碼。

#include <stdio.h>
#include <unistd.h>
#include <ohos_init.h>
#include <securec.h>
#include <los_base.h>
#include <cmsis_os.h>
#include "iunknown.h"
#include "feature.h"
#include "service.h"
#include "samgr_lite.h"
#include "time_adapter.h"
#include "discovery_service.h"

#define EXAMPLE_SERVICE "example"
#define EXAMPLE_FEATURE "example"

struct Payload{
    int id;
    const char *name;
    int value;
};

typedef struct DemoApi{
    INHERIT_IUNKNOWN;
    BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
    BOOL (*SyncCall)(IUnknown *iUnknown,struct Payload *payload);
} DemoApi;

typedef struct DemoFeature{
    INHERIT_FEATURE;
    INHERIT_IUNKNOWNENTRY(DemoApi);
    Identity identity;
} DemoFeature;

static BOOL AsyncCall(IUnknown *iUnknown, const char *body);
static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload);
static const char* FEATURE_GetName(Feature *feature);
static void FEATURE_OnInitialize(Feature *feature, Service* parent, Identity identity);
static void FEATURE_OnStop(Feature *feature, Identity identity);
static BOOL FEATURE_OnMessage(Feature *feature, Request *request);

static int g_regStep=0;

static const char *GetName(Service *service)
{
    (void)service;
    printf("GetService name:");
    return EXAMPLE_SERVICE;
}

static BOOL Initialize(Service *service, Identity identity)
{
    (void)identity;
    printf("[Boot Test][TaskID:%p][Step:%d][Reg Finish S:%s]Time: %llu!\n",
           osThreadGetId(), g_regStep++, service->GetName(service), SAMGR_GetProcessTime());
    return TRUE;
}

static BOOL MessageHandle(Service *service, Request *msg)
{
    printf("[Boot Test][TaskID:%p][Step:%d][S:%s] msgId<%d> \n",
           osThreadGetId(), g_regStep++, service->GetName(service), msg->msgId);
    return FALSE;
}

static TaskConfig GetTaskConfig(Service *service)
{
    (void)service;
    TaskConfig config = {LEVEL_HIGH, PRI_ABOVE_NORMAL,
                         0x400, 2, SHARED_TASK};
    return config;
}

static Service g_exampleService={
    .GetName=GetName,
    .Initialize=Initialize,
    .MessageHandle=MessageHandle,
    .GetTaskConfig=GetTaskConfig
};

static DemoFeature g_example={
    .GetName=FEATURE_GetName,
    .OnInitialize = FEATURE_OnInitialize,
    .OnStop = FEATURE_OnStop,
    .OnMessage = FEATURE_OnMessage,
    DEFAULT_IUNKNOWN_ENTRY_BEGIN,
    .AsyncCall=AsyncCall,
    .SyncCall=SyncCall,
    DEFAULT_IUNKNOWN_ENTRY_END,
    .identity = {-1, -1, NULL}
};

static const char* FEATURE_GetName(Feature *feature)
{
    printf("get feature name.");
    (void)feature;
    return EXAMPLE_FEATURE;
}

static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
{
    printf("Register Test,Oninit1");
    (void)parent;
    DemoFeature *demoFeature=(DemoFeature*)feature;
    demoFeature->identity=identity;
    printf("Register Test,Oninit");
}

static void FEATURE_OnStop(Feature *feature, Identity identity)
{
    (void)feature;
    (void)identity;
    g_example.identity.queueId = NULL;
    g_example.identity.featureId = -1;
    g_example.identity.serviceId = -1;
}

static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
{
    (void)feature;
    (void)request;
    printf("[LPC Test][TaskID:%p][Step:%d][OnMessage S:%s, F:%s] Inner Error! \n",
           osThreadGetId(), g_regStep++, EXAMPLE_SERVICE, feature->GetName(feature));
    return FALSE;
}

static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload)
{
    (void)iUnknown;
    if (payload != NULL && payload->id >= 0 && payload->name != NULL) {
        printf("[LPC Test][TaskID:%p][Step:%d][SyncCall API] Id:%d, name:%s, value:%d \n",
               osThreadGetId(), g_regStep++, payload->id, payload->name, payload->value);
        return TRUE;
    }
    printf("[LPC Test][TaskID:%p][Step:%d][SyncCall API] Input Error! \n", osThreadGetId(), g_regStep++);
    return FALSE;
}

static BOOL AsyncCall(IUnknown *iUnknown, const char *body)
{
    Request request = {.msgId = 1, .msgValue = 0};
    request.len = (uint32_t)(strlen(body) + 1);
    request.data = malloc(request.len);
    if (request.data == NULL) {
        return FALSE;
    }
    if (strcpy_s(request.data, request.len, body) != EOK) {
        free(request.data);
        return FALSE;
    }
    DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown);
    printf("[LPC Test][TaskID:%p][Step:%d][AsyncCall API] Send request! \n", osThreadGetId(), g_regStep++);
    return SAMGR_SendRequest(&feature->identity, &request, NULL);
}

static void OnPublishSuccess(int32_t publishId){
    printf("demo service publish success.%d",publishId);
}

static void onPublishFail(int32_t publishId, PublishFailReason reason)
{
    printf("OnPublishFail.%d,%d",publishId,(int32_t)reason);
}
//初始化工做,註冊Service後,再註冊Feature
static void Init(void)
{
    SAMGR_GetInstance()->RegisterService(&g_exampleService);
    SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE,(Feature*)&g_example);
    SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE,EXAMPLE_FEATURE,GET_IUNKNOWN(g_example));
    printf("[Register Test][TaskID:%d][Step:%d][Reg S:%s, F:%s] Time: %llu!\n",
            osThreadGetId(),g_regStep++,EXAMPLE_SERVICE,EXAMPLE_FEATURE,SAMGR_GetProcessTime());
}
//使用此方式初始化Feature
SYSEX_FEATURE_INIT(Init);

 

做者:mb5f8960971f61a

想了解更多內容,請訪問: 51CTO和華爲官方戰略合做共建的鴻蒙技術社區https://harmonyos.51cto.com

【免費直播公開課- 讓鴻蒙智能家居開發板與AWS IoT雲完美連通 】

相關文章
相關標籤/搜索