本文包含笔者对徐文礼老师的《鸿蒙操作系统开发入门经典》的学习过程中的笔记总结、拓展思考、案例反馈、阅读体验。

为尊重老师的知识产权和精简本文,本文不会粘贴代码、倒置案例、机械打字。

3.7 线程管理

3.7.1线程管理

时间:2021年7月24日08:50:383

注:这一部分书上跟开发文档基本上就是一样的

(from开发文档)

1.概述

  • 不同应用在各自独立的进程中运行。当应用以任何形式启动时,系统为其创建进程,该进程将持续运行。当进程完成当前任务处于等待状态,且系统资源不足时,系统自动回收。

  • 在启动应用时,系统会为该应用创建一个称为“主线程”的执行线程。该线程随着应用创建或消失,是应用的核心线程。UI界面的显示和更新等操作,都是在主线程上进行。主线程又称UI线程,默认情况下,所有的操作都是在主线程上执行。

  • 如果需要执行比较耗时的任务(如下载文件、查询数据库),可创建其他线程来处理。

2.场景介绍

  • 如果应用的业务逻辑比较复杂,可能需要创建多个线程来执行多个任务。这种情况下,代码复杂难以维护,任务与线程的交互也会更加繁杂。要解决此问题,开发者可以使用==“TaskDispatcher”==来分发不同的任务。

3.接口说明

  • TaskDispatcher是一个任务分发器,它是Ability分发任务的基本接口,隐藏任务所在线程的实现细节。

  • 为保证应用有更好的响应性,我们需要设计任务的优先级。在UI线程上运行的任务默认以高优先级运行。

  • TaskDispatcher具有多种实现,每种实现对应不同的任务分发器。在分发任务时可以指定任务的优先级,由同一个任务分发器分发出的任务具有相同的优先级。系统提供的任务分发器有GlobalTaskDispatcher、ParallelTaskDispatcher、SerialTaskDispatcher 、SpecTaskDispatcher。

为了更好地体现四个任务分发器的对比关系,笔者制表如下:

注:UITaskDispatcher、MainTaskDispatcher都属于专有任务分发器SpecTastDispatcher。建议使用UITaskDispatcher。

//GlobalTaskDispatcher全局并发任务分发器 TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); //ParallelTaskDispatcher并发任务分发器 String dispatcherName = "parallelTaskDispatcher"; TaskDispatcher parallelTaskDispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT); //SerialTaskDispatcher串行任务分发器 String dispatcherName = "serialTaskDispatcher"; TaskDispatcher serialTaskDispatcher = createSerialTaskDispatcher(dispatcherName, TaskPriority.DEFAULT); //SpecTaskDispatcher专有任务分发器 TaskDispatcher uiTaskDispatcher = getUITaskDispatcher();
  • 开发步骤总结

为了更好地体现开发任务的的对比关系,笔者制表如下:

3.7.2 线程间的通信

时间:2021年7月24日10:32:10

注:书中对于这一块也是和开发文档一模一样的。

学习总结:

目的:合理运用线程资源

元素:事件(InnerEvent)、任务(Runnable)、机制(EventHandler)、循环器(EventRunner)

场景:投递事件(双向)、投递任务、

方法:

  1. 创建机制子类并重写方法

  2. 创建循环器

  3. 创建机制子类实例

  4. 投递事件(需要获取事件实例)、投递任务

  5. 启动或停止机制

1.概述

  • 在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的操作,但是又不希望当前的线程受到阻塞。此时,就可以使用EventHandler机制。

  • EventHandler是HarmonyOS用于处理线程间通信的一种机制,可以通过EventRunner创建新线程,将耗时的操作放到新线程上执行。这样既不阻塞原来的线程,任务又可以得到合理的处理。

2.基本概念

  • EventRunner是一种事件循环器,循环处理从该EventRunner创建的新线程的事件队列中获取InnerEvent事件或者Runnable任务。InnerEvent是EventHandler投递的事件。

  • EventHandler是一种用户在当前线程上投递InnerEvent事件或者Runnable任务到异步线程上处理的机制。每一个EventHandler和指定的EventRunner所创建的新线程绑定,并且该新线程内部有一个事件队列。EventHandler可以投递指定的InnerEvent事件或Runnable任务到这个事件队列。

  • EventRunner从事件队列里循环地取出事件,如果取出的事件是InnerEvent事件,将在EventRunner所在线程执行processEvent回调;如果取出的事件是Runnable任务,将在EventRunner所在线程执行Runnable的run回调。一般,EventHandler有两个主要作用:

  • 在不同线程间分发和处理InnerEvent事件或Runnable任务

  • 延迟处理InnerEvent事件或Runnable任务。

3.运作机制

使用EventHandler实现线程间通信的主要流程:

1.EventHandler投递具体的InnerEvent事件或者Runnable任务到EventRunner所创建的线程的事件队列。

2.EventRunner循环从事件队列中获取InnerEvent事件或者Runnable任务。

3.处理事件或任务:

  • 如果EventRunner取出的事件为InnerEvent事件,则触发EventHandler的回调方法并触发EventHandler的处理方法,在新线程上处理该事件。

  • 如果EventRunner取出的事件为Runnable任务,则EventRunner直接在新线程上处理Runnable任务。

4.约束限制

  • 在进行线程间通信的时候,EventHandler只能和EventRunner所创建的线程进行绑定,EventRunner创建时需要判断是否创建成功,只有确保获取的EventRunner实例非空时,才可以使用EventHandler绑定EventRunner。

  • 一个EventHandler只能同时与一个EventRunner绑定,一个EventRunner可以同时绑定多个EventHandler。

5.EventRunner工作模式

EventRunner的工作模式可以分为托管模式和手动模式。两种模式是在调用EventRunner的create()方法时,通过选择不同的参数来实现的,详见API参考。默认为托管模式。

  • 托管模式:不需要开发者调用run()和stop()方法去启动和停止EventRunner。当EventRunner实例化时,系统调用run()来启动EventRunner;当EventRunner不被引用时,系统调用stop()来停止EventRunner。

  • 手动模式:需要开发者自行调用EventRunner的run()方法和stop()方法来确保线程的启动和停止。

6.EventRunner、EventHandler的接口很多。

7.三种开发应用

  • EventHandler投递InnerEvent事件

  • EventHandler投递Runnable任务

  • 在新创建的线程里将事件投递到原线程

3.6.17 系统剪贴板服务

时间:2021年7月24日08:28:14

系统剪贴板服务:在应用A中复制的数据,可以在应用B中粘贴

  • HarmonyOS提供了系统剪切板服务的操作接口

  • HarmonyOS提供了剪贴板数据的定义

注意:

  • 只有在前台获取焦点的应用才有读取系统剪切板的权限

  • 写入数据不会随应用程序结束而被销毁

  • 数据会被覆盖

  • 同一设备剪切板单次传递内容不应超过800KB

接口说明:

SystePastedboard提供了系统剪贴板操作的相关接口(复制、粘贴、配置回调)

PageData是剪贴板服务操作的数据对象,一个PageData由若干内容节点(PageData.Record)和一个属性集合对象(PageData.DataProperty)组成。

  • Record是存放剪贴板数据信息的最小单位,每个Record都有特定的MIME类型(文本、HTML、URL、Intent)

  • 剪贴板数据的属性存放在DataProperty(时间戳、标签)

开发步骤:

  • 获取服务

  • A写入数据

  • B读取数据

  • C添加数据变化回调

小总结

  • 线程管理中四种任务分发器、三种派发任务、三种基础操作、两种屏障需要多多熟悉,根据前几日做HCIA模拟题的经验,这部分出题是必然的。

  • 线程通信需要总体把握,目的、场景、元素、方法。

  • 剪贴板的原理一起都没有仔细学习过,感觉很简单,今日学习发现确实很简单,但有一些需要在开发的过程中注意的地方。