本文引言
时间:2021年7月24日08:28:18
本文包含笔者对徐文礼老师的《鸿蒙操作系统开发入门经典》的学习过程中的笔记总结、拓展思考、案例反馈、阅读体验。
为尊重老师的知识产权和精简本文,本文不会粘贴代码、倒置案例、机械打字。
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.概述
- 在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的操作,但是又不希望当前的线程受到阻塞。此时,就可以使用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模拟题的经验,这部分出题是必然的。
- 线程通信需要总体把握,目的、场景、元素、方法。
- 剪贴板的原理一起都没有仔细学习过,感觉很简单,今日学习发现确实很简单,但有一些需要在开发的过程中注意的地方。