当前位置:   article > 正文

鸿蒙应用开发培训笔记05:线程管理和数据管理_鸿蒙worker线程最大激活数

鸿蒙worker线程最大激活数

零、本讲学习目标

  1. 掌握如何进行线程管理和消息处理
  2. 熟悉TaskDispatcher线程管理框架
  3. 了解几种常用数据库的使用方式

一、线程管理

(一)线程与消息处理

1、主线程

  • 在启动应用时,系统会为该应用创建一个称为“主线程”的执行线程。默认情况下,所有的操作都是在主线程上执行。UI 界面的显示和更新等操作,都是在主线程上进行,所以主线程又称 UI 线程
    在这里插入图片描述

2、为什么需要多线程?

  • 举例,一个用于展示用户个人信息的页面,需要做到如下功能:
    – 展示初始页面
    – 下载配置文件包含昵称、生日和头像图片地址等信息
    – 根据头像图片地址下载图片
    – 展示昵称、生日以及头像
    在这里插入图片描述

以上操作都在主线程操作,会造成阻塞导致页面卡死!
在这里插入图片描述

3、使用多线程执行耗时操作

  • 将耗时的操作放到子线程上执行,这样既不阻塞主线程,任务又可以被合理的处理。
    在这里插入图片描述

4、如何实现跨线程通信

  • EventHandler是HarmonyOS用于处理线程间通信的一种机制,可以通过EventRunner创建新线程,将耗时的操作放到新线程上执行。
    在这里插入图片描述

5、事件处理器 - EventHandler

  • EventHandler的主要功能是将InnerEvent事件或者Runnable任务投递到其他的线程进行处理;使用EventHandler需要创建EventHandler的子类,并重写processEvent方法来处理事件。
    在这里插入图片描述

5、事件运行器 - EventRunner

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

  • 托管模式:不需要开发者调用run()和stop()方法去启动和停止EventRunner。当EventRunner实例化时,系统调用run()来启动EventRunner;当EventRunner不被引用时,系统调用stop()来停止EventRunner。
  • 手动模式:需要开发者自行调用EventRunner的run()方法和stop()方法来确保线程的启动和停止。
EventRunner runner = EventRunner.create(false); // create()的参数是true或无参数时,为托管模式
  • 1

6、跨线程消息处理示例

  • 以主线程与子线程进行通信为例,子线程执行耗时任务,将任务结果发送给主线程处理并展示。时序图如下:
    在这里插入图片描述

7、线程间通信开发示例

(1)创建EventHandler的子类
private class MyEventHandler extends EventHandler {@Override
    protected void processEvent(InnerEvent event) {
        super.processEvent(event);
        // 从 InnerEvent 对象中取出信息并处理}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
(2)创建EventRunner对象
EventRunner runner = EventRunner.create(); // EventRunner 默认为托管模式
  • 1
(3)通过事件处理器发送消息
myHandler.sendEvent(event1, 0, EventHandler.Priority.IMMEDIATE);
  • 1

(二)线程管理框架 - TaskDispatcher

1、为什么需要线程管理框架?

  • 应用的业务逻辑比较复杂时,需要创建多个线程来执行多个任务
  • 多任务与多线程的交互较为繁杂时,代码复杂难以维护
  • 此时,可以使用 “TaskDispatcher” 来分发不同的任务
getGlobalTaskDispatcher(TaskPriority.DEFAULT).syncDispatch(new Runnable() {
    @Override
    public void run() {
        // 执行操作getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                // 更新 UI}
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2、任务分发器

(1)任务分发器概述
  • TaskDispatcher是一个任务分发器,它是Ability分发任务的基本接口,隐藏任务所在线程的实现细节。
  • 为保证应用有更好的响应性,需要设计任务的优先级。在UI线程上运行的任务默认以高优先级运行,如果某个任务无需等待结果,则可以用低优先级。
    在这里插入图片描述
(2)任务分发器实现
  • TaskDispatcher具有多种实现,每种实现对应不同的任务分发器。
    在这里插入图片描述
(3)任务派发方法
  • syncDispatch():同步派发任务。派发任务并在当前线程等待任务执行完成。在返回前,当前线程会被阻塞。如果使用不当,将会导致死锁。

  • asyncDispatch():异步派发任务。派发任务,并立即返回,返回值是一个可用于取消任务的接口。

  • delayDispatch():异步延迟派发任务。异步执行,函数立即返回,内部会在延时指定时间后将任务派发到相应队列中。延时时间参数仅代表在这段时间以后任务分发器会将任务加入到队列中,任务的实际执行时间可能晚于这个时间。

  • group():表示成组派发任务,且该组任务之间有一定的联系。

(三)思考题

  1. (判断题) 使用syncDispatch可能导致死锁。( )
    A. 正确
    B. 错误
  2. (单选题) 在UI线程上运行的任务默认以( )优先级运行。
    A. HIGH
    B. DEFAULT
    C. LOW
    D. NONE
  3. (单选题) 一个 EventHandler 可以与( )个 EventRunner 绑定,一个 EventRunner 上可以创建( )个 EventHandler。
    A. 一,一
    B. 多,多
    C. 多,一
    D. 一,多

二、数据管理

(一)常用数据库

1、为什么需要使用数据库管理数据?

  • 检索数据时,数据库耗时较低,资源占用小。
  • 面对庞大的数据,不可能将所有数据都载入内存,如果频繁进行 IO 操作,性能损耗较大。
  • 管理数据时,使用数据库可以降低一些常规操作的代码量。
  • 数据库普遍支持增量写入,安全性较好。
  • 主流数据库性能普遍较好。

2、关系数据库

(1)基本概念
  • 是一种基于关系模型来管理数据的数据库
  • 基于SQLite组件提供对本地数据库进行管理的机制
  • 对外提供增、删、改、查接口,也可以直接运行输入的SQL语句
(2)运作机制
  • 对外提供通用的操作接口
  • 底层使用SQLite作为持久化存储引擎
  • 支持SQLite具有的所有数据库特性
    在这里插入图片描述

3、对象关系映射 - ORM

(1)基本概念

对象关系映射 (Object Relational Mapping, ORM) 数据库框架屏蔽了底层SQLite数据库的SQL操作,针对实体和关系提供了增删改查等面向对象接口,支持以操作对象的形式来操作数据库。

(2)三个主要组件
  • 数据库:使用@Database注解,且继承了OrmDatabase的类,对应关系型数据库。
  • 实体对象:使用@Entity注解,且继承了OrmObject的类,对应关系型数据库中的表。
  • 对象数据操作接口:包括数据库操作的入口OrmContext类和谓词接口 (OrmPredicate) 等。
    在这里插入图片描述
(3)运作机制
  • 对象关系映射数据库操作基于关系型数据库操作接口实现,并其基础上实现了对象关系映射等特性。
  • 使用前需要先配置实体模型与关系映射文件,类生成工具会解析这些文件,生成数据库帮助类。
  • 框架在运行时,会根据配置创建数据库,并在存储过程中自动完成对象关系映射。
    在这里插入图片描述

4、轻量级偏好数据库

(1)基本概念
  • Key-Value数据库:一种以键值对存储数据的数据库,类似Java中的map。Key是关键字,Value是值。
  • 非关系型数据库:区别于关系数据库,不保证遵循 ACID (Atomic, Consistency, Isolation and Durability) 特性,不采用关系模型来组织数据,数据之间无关系,扩展性好。
  • 偏好数据:用户经常访问和使用的数据。
    在这里插入图片描述
(2)运作机制
  • 应用通过偏好型数据库操作类完成数据库操作。
  • 应用借助DatabaseHelper API将指定文件的内容加载到Preferences实例,该实例会存储在内存中,直到应用主动从内存中移除该实例或者删除该文件。
  • 应用使用Preferences API进行读写操作,通过flush或者flushSync将Preferences实例持久化。
    在这里插入图片描述
(3)代码示例
  • 获取Preferences实例
// context 入参类型为 ohos.app.Context
DatabaseHelper databaseHelper = new DatabaseHelper(context); 
// fileName 表示文件名,其取值不能为空,也不能包含路径
String fileName = "name"; 
Preferences preferences = databaseHelper.getPreferences(fileName);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 读取数据
int value = preferences.getInt("intKey", 0);
  • 1
  • 异步写入数据
preferences.putInt("intKey", 3);
preferences.putString("StringKey", "String value");
preferences.flush();
  • 1
  • 2
  • 3
  • 同步写入数据
preferences.putInt("intKey", 3);
preferences.putString("StringKey", "String value");
preferences.flushSync();
  • 1
  • 2
  • 3

5、数据库对比

在这里插入图片描述

(二)分布式数据文件服务

1、多设备协同时如何处理数据和文件?

多设备协同时,处理数据和文件需要做到:

  • 对不同设备上的数据执行增、删、改、查操作
  • 对不同设备上的文件执行读、写操作
  • 对不同设备上的数据库和文件执行同步操作

HarmonyOS 基于分布式软总线提供了去中心化的分布式数据服务和分布式文件服务。
在这里插入图片描述

2、分布式数据服务

(1)基本概念

在这里插入图片描述

(2)代码示例
  • 根据配置构造分布式数据库管理类实例
KvManagerConfig config = new KvManagerConfig(context);
KvManager kvManager = KvManagerFactory.getInstance().createKvManager(config);
  • 1
  • 2
  • 获取/创建单版本分布式数据库
Options CREATE = new Options();
CREATE.setCreateIfMissing(true).setEncrypt(false).setKvStoreType(KvStoreType.SINGLE_VERSION);
SingleKvStore singleKvStore = kvManager.getKvStore(CREATE, "storeID");
  • 1
  • 2
  • 3
  • 在不同的设备上,分别将数据写入单版本分布式数据库,或从中查询数据
    在这里插入图片描述

3、分布式文件服务

(1)基本概念

在这里插入图片描述

(2)代码示例
  • 设备1上的应用A创建文件,并写入内容
File distDir = context.getDistributedDir();
String filePath = distDir + File.separator + "hello.txt";
FileWriter fileWriter = new FileWriter(filePath, true);
fileWriter.write("Hello World");
fileWriter.close();
- 设备2上的应用A通过Context.getDistributedDir()接口获取分布式目录
- 设备2上的应用A读取文件

```java
FileReader fileReader = new FileReader(filePath);
char[] buffer = new char[1024];        
fileReader.read(buffer);        
fileReader.close();        
System.out.println(buffer);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(三)思考题

  1. (判断题) 使用轻量级偏好数据库写入数据时,flush()用于同步写入,flushSync()用于异步写入。( )
    A. 正确
    B. 错误
  2. (判断题) 关系型数据库和对象型关系数据库的底层都是基于SQLite数据库。( )
    A. 正确
    B. 错误
  3. (单选题) 下面哪种数据库可以直接运行输入的SQL语句?( )
    A. 关系型数据库
    B. 对象关系映射数据库
    C. 轻量级偏好数据库
    D. 分布式数据服务

三、本讲总结

讲述了HarmonyOS线程管理的方式和场景,帮助开发者了解如何通过多线程的方式提高应用运行效能。还介绍了常用的数据存储和管理方式,包括关系型数据库、轻量级偏好数据库等,开发过程中可以根据业务的情况选择最合适的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/283244
推荐阅读
相关标签
  

闽ICP备14008679号