HarmonyOS实战—时钟卡片

​​​​​​​ 目录

一、时钟卡片简介:

 二、开发环境搭建:

第一步:创建一个空的工程文件:

使用JS开发卡片:

 标签”forms”中卡片的配置:

 卡片的定点/定时刷新:

时钟卡片配置文件:

卡片布局:

创建卡片:

创建卡片数据库:

卡片应用初始化:

更新卡片:

前台service

卡片组件更新


一、时钟卡片简介:

        服务卡片是FA的一种界面展示形式,将FA重要信息或操作前置到卡片,以此达到服务直达、减少层级体验的目的。

        这里将介绍如何在HarmonyOS上开发一个时钟类FA卡片应用,该卡片包含2*2、2*4两种布局样式,卡片应用在桌面上的显示效果如下:


 二、开发环境搭建:

安装和配置DevEco Studio,详情请参考我的入门篇博客:下载和安装软件

这次实战使用的是DevEco Studio版本为DevEco Studio 2.1 Beta4,使用的SDK版本为API Version 5

第一步:创建一个空的工程文件:

        创建一个HarmonyOS的工程,然后选择模板Empty Ability(JS)或Empty Ability(Java),点击按钮Next,进入到工程配置界面:(这里,使用的是SDK版本为API Version 5)

        其中,工程类型有两种:一种是”Service”,也就是原子化服务;另一种是”Application”,也就是传统的应用。此外,还可以选择”是否在服务中心进行展示”。我们将工程类型指定为”原子化服务”,并且选择”在服务中心进行展示”。按照上图进行配置之后,点击按钮Finish以创建一个工程。

连接远程设备: 

 开启远程设备:


使用JS开发卡片:

        打开DevEco Studio,创建一个HarmonyOS的工程,然后选择模板Empty Ability(JS),点击按钮Next,进入到工程配置界面:

        其中,将工程类型指定为传统应用,并且不选择”在服务中心进行展示”。按照上图进行配置之后,点击按钮Finish以创建一个工程。

        如何在一个传统应用的工程中创建卡片呢?

        在目录entry上点击右键,在弹出的菜单中选择New,然后在弹出的子菜单中点击Service Widget:

这里的Service Widget指的就是卡片。

        在模板选择界面,选择基本的模板Grid Pattern,点击按钮Next,进入到卡片配置界面: 

        首先配置卡片的名称和描述;然后配置卡片关联的Page Ability;然后配置卡片的编程语言类型是JS;接下来配置卡片的JS组件名称;最后配置卡片支持的规格,其中,2*2的小尺寸是必须要支持的,我们再勾选一个1*2的微尺寸。点击按钮Finish以创建一个卡片。

再创建2*4的中尺寸和4*4的大尺寸:

DevEco Studio会自动帮我们生成了一些目录和文件:

  •  widget01和widget02是创建卡片时配置的JS组件名称
  • index.hml中定义了卡片中包含哪些UI组件;index.css中定义了卡片中的UI组件样式
  • index.json中定义了卡片中动态绑定的数据,此外,还可以定义click触发事件

        widget01和widget01是创建卡片时配置的卡片名称;在MainAbility中添加了卡片的生命周期回调方法,如:onCreateForm()、onUpdateForm()、onTriggerFormEvent()、等。 还添加了FormControllerManager、FormController、以及两个以Impl结尾的实现类。

        在config.json中自动添加了很多配置:

{
  "app": {
    "bundleName": "com.example.demo",
    "vendor": "example",
    "version": {
      "code": 1000000,
      "name": "1.0.0"
    }
  },
  "deviceConfig": {},
  "module": {
    "package": "com.example.demo",
    "name": ".MyApplication",
    "mainAbility": "com.example.demo.MainAbility",
    "deviceType": [
      "phone"
    ],
    "distro": {
      "deliveryWithInstall": true,
      "moduleName": "entry",
      "moduleType": "entry",
      "installationFree": true
    },
    "abilities": [
      {
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ],
        "name": "com.example.demo.MainAbility",
        "icon": "$media:icon",
        "description": "$string:mainability_description",
        "label": "$string:entry_MainAbility",
        "type": "page",
        "launchType": "standard",
        "formsEnabled": true,
        "forms": [
          {
            "jsComponentName": "widget01",
            "isDefault": true,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget01",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "JS",
            "supportDimensions": [
              "1*2",
              "2*2"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          },
          {
            "jsComponentName": "widget02",
            "isDefault": false,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget02",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "JS",
            "supportDimensions": [
              "2*2",
              "2*4",
              "4*4"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          }
        ]
      }
    ],
    "js": [
      {
        "pages": [
          "pages/index/index"
        ],
        "name": "default",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        }
      },
      {
        "pages": [
          "pages/index/index"
        ],
        "name": "widget01",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        },
        "type": "form"
      },
      {
        "pages": [
          "pages/index/index"
        ],
        "name": "widget02",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": true
        },
        "type": "form"
      }
    ]
  }
}

        MainAbility添加了标签”forms”,这里的form就是卡片的意思,和Service Widget是一回事儿。”forms”是一个数组,包含两个元素,分别表示我们创建的两个卡片。顺便提一下,在前面我们有讲到:“可以在config.json中为每个Page Ability配置0~16个卡片”,也就是说,数组”forms”中最多可以包含16个元素。上图的最下方还添加了一个标签”js”,”js”也是一个数组,包含三个元素,其中后两个元素就是两个卡片对应的js组件,”name”分别是”widget01”和”widget02”,这两个值就对应着上面的标签”forms”中”jsComponentName”的两个值。也就是说,上面的标签”forms”中卡片的js组件,是在下面的标签”js”中定义的。

 标签”forms”中卡片的配置:

  • “isDefault”表示该卡片是否为默认的上滑卡片,也就是用手指按下应用图标的同时往上滑时弹出的卡片。
  • “scheduledUpdateTime”表示卡片定点刷新的时刻,采用24小时制,精确到分钟。
  • “defaultDimension“表示卡片的默认尺寸规格,取值必须在下面的“supportDimensions“所配置的列表中。
  • “colorMode“表示卡片的主题样式,默认值是”auto”,表示自适应,还可以取值为”dark”或”light”,分别表示深色主题和浅色主题。
  • “supportDimensions“表示卡片支持的尺寸规格,也就是我们在创建卡片时配置的尺寸规格。
  • “updateEnabled”表示卡片是否支持定时刷新或定点刷新,优先选择定时刷新。
  • “updateDuration“表示卡片定时刷新的周期。当取值为0时,表示该参数不生效;当取值为正整数N时,表示刷新周期为30*N分钟。

         由于该工程的类型是”原子化服务”,所以在桌面上并没有相应的图标。由于在创建工程时选择了”在服务中心进行展示”,因此,打开服务中心,就看到了相应的入口卡片:

上下滑动所有卡片,总共有5个:

  • widget01的卡片有两个,尺寸分别是1*2和2*2
  • widget02的卡片有三个,尺寸分别是2*2、2*4和4*4

        widget1的2*2的卡片被设为了上滑卡片,这是因为:在config.json中,将”isDefault”设为了”true”,并且将”defaultDimension”设为了” 2*2”:

"forms": [
          {
            "jsComponentName": "widget",
            "isDefault": true,
            "scheduledUpdateTime": "10:30",
            "defaultDimension": "2*2",
            "name": "widget",
            "description": "This is a service widget",
            "colorMode": "auto",
            "type": "JS",
            "supportDimensions": [
              "2*2"
            ],
            "updateEnabled": true,
            "updateDuration": 1
          },

        在桌面上长按应用的图标然后显示所有卡片的时候,MainAbility中卡片的生命周期方法onCreateForm()会被自动回调,方法onCreateForm()的实现:

    @Override
    protected ProviderFormInfo onCreateForm(Intent intent) {
        HiLog.info(TAG, "onCreateForm");
        long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
        String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
        int dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
        HiLog.info(TAG, "onCreateForm: formId=" + formId + ",formName=" + formName);
        FormControllerManager formControllerManager = FormControllerManager.getInstance(this);
        FormController formController = formControllerManager.getController(formId);
        formController = (formController == null) ? formControllerManager.createFormController(formId,
                formName, dimension) : formController;
        if (formController == null) {
            HiLog.error(TAG, "Get null controller. formId: " + formId + ", formName: " + formName);
            return null;
        }
        return formController.bindFormData();
    }

因为总共有5个卡片,所以方法onCreateForm()会被回调5次!!!

方法bindFormData():

@Override
    public ProviderFormInfo bindFormData() {
        HiLog.info(TAG, "bind form data");
        ZSONObject zsonObject = new ZSONObject();
        ProviderFormInfo providerFormInfo = new ProviderFormInfo();
        if (dimension == DIMENSION_1X2) {
            zsonObject.put("mini", true);
        }
        if (dimension == DIMENSION_2X4) {
            zsonObject.put("dim2X4", true);
        }
        providerFormInfo.setJsBindingData(new FormBindingData(zsonObject));
        return providerFormInfo;
    }

         程序根据卡片的尺寸,分别设置了两个变量”mini”和”dim2X4”的值,这两个变量是子目录widget01中的index.json中的两个变量。

{
  "data": {
    "mini": false,
    "dim2X4": false,
    "miniTitle": "Title",
    "title": "Title",
    "content": "Introduction",
    "detailTitle": "Title"
  }
}

        这里顺便说一下,在index.hml中,很多变量都使用两个花括号括了起来,这些变量的值是在程序的运行过程中动态确定的,这种技术称之为动态绑定。这些变量的初始值在index.json中的标签”data”中进行了定义。所以,在方法bindFormData()中,根据卡片的尺寸修改了两个动态绑定的变量的值。

 所有卡片的标题都被修改了(尺寸最小的卡片除外,因为他本来就不显示标题)。

 卡片的定点/定时刷新:

        打开config.json,先将widget02对应的标签”updateDuration”修改为0,以关闭定时刷新。

         对于标签“scheduledUpdateTime”设定的时刻,当到达之后,MainAbility中卡片的回调方法onUpdateForm()就会被自动调用:

        将要刷新的数据存放在一个ZSONObject实例中,然后,将其封装在一个FormBindingData的实例bindingData中,最后,调用MainAbility的方法updateForm(),并将bindingData作为第二个实参。

@Override
    public void updateFormData(long formId, Object... vars) {
        HiLog.info(TAG, "update form data timing, default 30 minutes");

        //刷新数据:
        ZSONObject data = new ZSONObject();
        data.put("title","更新操作");
        FormBindingData bindingData = new FormBindingData(data);
        try {
            ((MainAbility)context).updateForm(formId, bindingData);
        } catch (FormException e) {
            HiLog.error(TAG,e.toString());
        }
    }

 打开config.json,将标签“scheduledUpdateTime”的值修改为当前时刻的一分钟之后:

        运行工程,将widget02对应的卡片都添加到桌面上,当到达设定的定点时刻之后,卡片标题都刷新了:


时钟卡片配置文件:

"forms": [ 
  { 
        "landscapeLayouts": [ 
          "$layout:form_image_with_info_date_card_2_2", 
          "$layout:form_image_with_info_date_card_2_4" 
        ], 
        "isDefault": true, 
        "scheduledUpdateTime": "10:30", 
        "defaultDimension": "2*2", 
        "name": "DateCard", 
        "description": "This is a service widget", 
        "colorMode": "auto", 
        "type": "Java", 
        "supportDimensions": [ 
          "2*2", 
          "2*4" 
        ], 
        "portraitLayouts": [ 
          "$layout:form_image_with_info_date_card_2_2", 
          "$layout:form_image_with_info_date_card_2_4" 
        ], 
        "updateEnabled": true, 
        "updateDuration": 1, 
        "formVisibleNotify": true 
  } 
]

卡片布局:

        以2*2布局为例,详细进行介绍。整个2*2卡片展示的内容从上到下分别为日期、时间、星期,整体由DependentLayout布局内嵌套四个DirectionalLayout构成,每个DirectionalLayout 内均使用Text组件进行展示,部分代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<DependentLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:height="match_parent" 
    ohos:width="match_parent" 
    ohos:background_element="#6A9F99" 
    ohos:remote="true"> 
    <DirectionalLayout 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:orientation="vertical" 
        > 
        <Text...> 
     </DirectionalLayout> 
     <DirectionalLayout 
         ohos:id="$+id:title" 
         ohos:height="match_content" 
         ohos:width="match_parent" 
         ohos:alignment="horizontal_center" 
         ohos:orientation="horizontal" 
         ohos:top_margin="35fp" 
         > 
        <Text...> 
        <Text...> 
        <Text...> 
      </DirectionalLayout> 
 
     <DirectionalLayout 
         ohos:id="$+id:time" 
         ohos:height="match_content" 
         ohos:width="match_parent" 
         ohos:alignment="horizontal_center" 
         ohos:below="$id:title" 
         ohos:orientation="horizontal" 
         ohos:top_margin="0.5fp" 
         > 
         <Text...> 
         <Text...> 
         <Text...> 
         <Text...> 
         <Text...> 
     </DirectionalLayout> 
 
     <DirectionalLayout 
         ohos:height="match_content" 
         ohos:width="match_parent" 
         ohos:alignment="center" 
         ohos:below="$id:time" 
         ohos:margin="20fp" 
         ohos:orientation="horizontal" 
      > 
         <Text...> 
         <Text...> 
         <Text...> 
         <Text...> 
         <Text...> 
         <Text...> 
         <Text...> 
     </DirectionalLayout> 
</DependentLayout>

创建卡片:

创建卡片数据库:

        使用对象关系映射数据库来对卡片ID,卡片名字等信息进行存储,我们创建了一个数据库(FormDatabase)和一张表(Form)。
首先定义了数据库类FormDatabase.java,数据库包含"Form"表,版本号为 "1",示例代码如下:

@Database( 
    entities = {Form.class}, 
    version = 1) 
public abstract class FormDatabase extends OrmDatabase {}

        定义实体类Form.java,对应数据库内的表名为"form",包含了卡片id"formId"(主键),卡片名称"formName"和卡片规格"dimension"三个字段,示例代码如下:

@Entity(tableName = "form") 
public class Form extends OrmObject { 
    @PrimaryKey() 
    private Long formId; 
    private String formName; 
    private Integer dimension; 
    
    public Form(Long formId, String formName, Integer dimension) { 
        this.formId = formId; 
        this.formName = formName; 
        this.dimension = dimension; 
    } 
    // 自行添加字段的getter和setter方法或者参考完整代码 
}

卡片应用初始化:

卡片程序安装启动后,会进入MainAbility,在onStart时,会首先启动卡片定时器服务TimerAbility,以便刷新时钟卡片,部分示例代码如下:

@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    connect = helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class); 
    // 启动TimerAbility 
    Intent intentService = new Intent(); 
    Operation operation = 
            new Intent.OperationBuilder() 
                    .withDeviceId("") 
                    .withBundleName("com.huawei.cookbooks") 
                    .withAbilityName("com.huawei.cookbooks.TimerAbility") 
                    .build(); 
    intentService.setOperation(operation); 
    startAbility(intentService); 
    super.setMainRoute(ClockCardSlice.class.getName()); 
}

        ​​​​​​​当卡片使用方请求获取卡片时,卡片提供方会被拉起并调用onCreateForm回调函数,完成卡片信息的初始化,在MainAbility中有如下示例代码:

@Override 
protected ProviderFormInfo onCreateForm(Intent intent) { 
    if (intent == null) { 
        return new ProviderFormInfo(); 
    } 
    // 获取卡片id 
    formId = INVALID_FORM_ID; 
    if (intent.hasParameter(AbilitySlice.PARAM_FORM_IDENTITY_KEY)) { 
        formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID); 
    } else { 
        return new ProviderFormInfo(); 
    } 
    // 获取卡片名称 
    String formName = EMPTY_STRING; 
    if (intent.hasParameter(AbilitySlice.PARAM_FORM_NAME_KEY)) { 
        formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY); 
    } 
    // 获取卡片规格 
    int dimension = DEFAULT_DIMENSION_2X2; 
    if (intent.hasParameter(AbilitySlice.PARAM_FORM_DIMENSION_KEY)) { 
        dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2); 
    } 
    int layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_2; 
    if (dimension == DEFAULT_DIMENSION_2X4) { 
        layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_4; 
    } 
    formInfo = new ProviderFormInfo(layoutId, this); 
    // 存储卡片信息 
    Form form = new Form(formId, formName, dimension); 
    ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, this); 
    formInfo.mergeActions(componentProvider); 
    if (connect == null) { 
        connect = 
                helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class); 
    } 
    try { 
        DatabaseUtils.insertForm(form, connect); 
    } catch (Exception e) { 
        DatabaseUtils.deleteFormData(form.getFormId(), connect); 
    } 
    return formInfo; 
}

当卡片被删除时,需要重写onDeleteForm方法,根据卡片id删除卡片实例数据:

@Override 
protected void onDeleteForm(long formId) { 
    super.onDeleteForm(formId); 
    // 删除数据库中的卡片信息 
    DatabaseUtils.deleteFormData(formId, connect); 
}

更新卡片:

为了方便处理时钟卡片刷新的定时任务,我们创建了一个Service Ability,定时去更新卡片信息,在TimerAbility.java中有如下部分参考代码:

@Override
public void onStart(Intent intent) {
    connect = helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class);
    startTimer();
    super.onStart(intent);
}
// 卡片更新定时器,每秒更新一次 
private void startTimer() {
    Timer timer = new Timer();
    timer.schedule(
            new TimerTask() {

                @Override

                public void run() {

                    updateForms();
                    notice();

                }
            },

            0,SEND_PERIOD);
}

private void updateForms() {
    // 从数据库中获取卡片信息 
    OrmPredicates ormPredicates = new OrmPredicates(Form.class);
    List<Form> formList = connect.query(ormPredicates);
    // 更新时分秒 
    if (formList.size() > 0) {
        for (Form form : formList) {
            // 遍历卡片列表更新卡片 
            ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, this);
            try {

                Long updateFormId = form.getFormId();

                updateForm(updateFormId, componentProvider);
            } catch (FormException e) {
                // 删除不存在的卡片 
                DatabaseUtils.deleteFormData(form.getFormId(), connect);
                HiLog.error(LABEL_LOG, "onUpdateForm updateForm error");
            }
        }
    }
}

前台service

为了保持service不被系统销毁,需要使用前台service配合手机管家中的相关配置来达到目的。示例代码如下:

private void notice() { 
        // 创建通知 
        NotificationRequest request = new NotificationRequest(NOTICE_ID); 
        request.setAlertOneTime(true); 
        NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent(); 
        content.setText(DateUtils.getCurrentDate("yyyy-MM-dd HH:mm:ss")); 
        NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content); 
        request.setContent(notificationContent); 
        // 绑定通知 
        keepBackgroundRunning(NOTICE_ID, request); 
}

卡片组件更新

        有关卡片组件的更新,我们封装了ComponentProviderUtils这个类,在卡片更新时候,通过调用updateForm方法,传入参数formId和componentProvider,以达到日期、时间和星期实时更新的效果,部分代码和效果如下:

public static ComponentProvider getComponentProvider(Form form, Context context) { 
    int layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_2; 
    if (form.getDimension() == DIM_VERSION) { 
        layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_4; 
    } 
    ComponentProvider componentProvider = new ComponentProvider(layoutId, context); 
    setComponentProviderValue(componentProvider); 
    return componentProvider; 
} 
 
// 为时钟各个组件赋值 
private static void setComponentProviderValue(ComponentProvider componentProvider) { 
    Calendar now = Calendar.getInstance(); 
    int hour = now.get(Calendar.HOUR_OF_DAY); 
    int min = now.get(Calendar.MINUTE); 
    int second = now.get(Calendar.SECOND); 
    String hourString = int2String(hour); 
    String minString = int2String(min); 
    String secondString = int2String(second); 
    componentProvider.setText(ResourceTable.Id_date, DateUtils.getCurrentDate("yyyy-MM-dd")); 
    componentProvider.setText(ResourceTable.Id_hour, hourString); 
    componentProvider.setText(ResourceTable.Id_min, minString); 
    componentProvider.setText(ResourceTable.Id_sec, secondString); 
 
    // 获取当前星期 
    int weekDayId = getWeekDayId(); 
    componentProvider.setTextColor(weekDayId, nowWeekColor); 
 
    // 将前一天的星期改回原色 
    int lastWeekId = getLastWeekDayId(); 
    componentProvider.setTextColor(lastWeekId, primaryWeekColor); 
}

参考官网文档:JAVA时钟卡片


【本文正在参与"有奖征文|HarmoneyOS征文大赛"活动】

传送口:https://marketing.csdn.net/p/ad3879b53f4b8b31db27382b5fc65bbc

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
华为鸿蒙HarmonyOS开发整理资料汇总,共38份。 1学前必读:HarmonyOS学习资源主题分享 2学前必读:OpenHarmony-联盟生态资料合集 3-1.HarmonyOS概述:技术特性 3-2.HarmonyOS概述:开发工具与平台 3-3.HarmonyOS概述:系统安全 3-4.HarmonyOS概述:系统定义 3-5.HarmonyOS概述:下载与安装软件 3-6.HarmonyOS概述:应用开发基础知识 3-7.HarmonyOS概述:最全HarmonyOS文档和社区资源使用技巧 4-1.生态案例:【开发者说】重塑经典,如何在HarmonyOS手机上还原贪吃蛇游戏 4-2.生态案例:HarmonyOLabo涂鸦鸿蒙亲子版 4-3.生态案例:HarmonyOS分镜头APP案例 4-4.生态案例:HarmonyOS时光序历史学习案例 4-5.生态案例:HarmonyOS先行者说 宝宝巴士携手HarmonyOS共同打造儿童教育交互新体验 4-6.生态案例:HarmonyOS智能农场物联网连接实践 4-7.生态案例:分布式开发样例,带你玩转多设备 4-8.生态案例:华为分布式日历应用开发实践 5-1.【Codelab】HarmonyOS基于图像模块实现图库图片的四种常见操作 5-2.【CodeLab】手把手教你创建第一个手机“Hello World” 5-3.【Codelab】如此简单!一文带你学会15个HarmonyOS JS组件 5-4.【Codelab】懒人“看”书新法—鸿蒙语音播报,到底如何实现? 5-5.【Codelab】基于AI通用文字识别的图像搜索,这波操作亮了 5-6.【Codelab】开发样例概览 6-1.技术解读之HarmonyOS轻量JS开发框架与W3C标准差异分析 6-2.技术解读之HarmonyOS驱动加载过程分析 6-3.技术解读之HarmonyOS组件库使用实践 6-4.技术解读之华为架构师解读:HarmonyOS低时延高可靠消息传输原理 6-5.技术解读之解密HarmonyOS UI框架 6-6.技术解读之如何从OS框架层面实现应用服务功能解耦 7-1.常见问题之HarmonyOS元服务的设计与开发解析 7-2.常见问题之Java开发 7-3.常见问题之JS开发 7-4.常见问题之模拟器登录 7-5.常见问题之模拟器运行 7-6.常见问题之如何使用JsJava开发HarmonyOS UI 7-7.常见问题之应用配置 7-8.常见问题之预览器运行 8【视频合集】入门到进阶视频学习资料合集30+
HarmonyOS是华为公司自主研发的操作系统,其内核是实现系统各项功能的核心部分。对于HarmonyOS内核源码的分析,可以从以下几个方面进行讨论。 首先,HarmonyOS内核源码的分析可以关注其整体架构。HarmonyOS内核采用微内核架构,将各个功能模块拆分成独立的服务,通过消息传递进行通信,实现了更高的灵活性和可靠性。通过分析内核的整体架构,可以深入了解到HarmonyOS是如何进行进程管理、内存管理、文件系统等各个方面的功能实现。 其次,可以重点关注HarmonyOS内核的调度机制。调度机制是操作系统内核决定进程、线程执行顺序和时间分配的重要部分。HarmonyOS内核采用了全局时钟中断驱动的抢占式调度机制,能够确保不同任务的公平和高效执行。通过对调度机制的分析可以了解到HarmonyOS内核是如何进行多任务切换、时间片轮转以及任务优先级管理的。 此外,HarmonyOS内核源码分析还可以关注线程同步和通信机制。线程同步和通信是多线程协作的基础,也是操作系统内核重要的功能之一。HarmonyOS内核通过互斥锁、条件变量和信号量等机制实现了线程之间的同步和通信。了解这些机制可以更好地理解HarmonyOS是如何处理多线程并发访问共享资源和协调线程之间的执行顺序的。 最后,分析HarmonyOS内核源码还可以关注其安全性。安全性是一个操作系统内核不能忽视的重要问题。HarmonyOS内核采用了多种安全机制,如安全IPC、安全网卡等,确保系统资源和用户数据的安全。通过分析内核源码中的安全措施可以了解到HarmonyOS是如何保障系统的安全性并防止恶意攻击。 综上所述,对于HarmonyOS内核源码的分析需要关注整体架构、调度机制、线程同步和通信机制以及安全性等方面。通过深入分析内核源码,可以更好地了解操作系统的具体实现细节和原理,为开发者提供更好的参考和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃糖的范同学

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值