当前位置: 首页 > news >正文

AOSP Android14 Launcher3——RecentsView最近任务数据加载

最近任务是Launcher中的一个重要的功能,显示用户最近使用的应用,并可以快速切换到其中的应用;用户可以通过底部上滑停顿进入最近任务,也可以在第三方应用底部上滑进最近任务。

这两种场景之前的博客也介绍过,本文就不再赘述。
本篇就来讲讲最近任务中的这些任务卡片是如何一步步加载并显示在页面上的。

RecentsView

这个类是最近任务的核心类。
RecentsView继承自PagedView,所以,这个页面可以上下或者左右滚动,展示最近任务卡片并快速滚动。
最近任务卡片即TaskView,是最近任务RecentsView的childView。RecentsView将TaskView通过addView的方式添加到界面上。如图所示。

在这里插入图片描述
RecentsView是如何将TaskView添加的呢?其中显示的每个Task的数据哪里来的呢?

这里就涉及到一个重要的方法reloadIfNeed

 // quickstep/src/com/android/quickstep/views/RecentsView.java/*** Reloads the view if anything in recents changed.*/public void reloadIfNeeded() {if (!mModel.isTaskListValid(mTaskListChangeId)) {mTaskListChangeId = mModel.getTasks(this::applyLoadPlan, RecentsFilterState.getFilter(mFilterState.getPackageNameToFilter()));}}

这个方法通过RecentsModel的方法getTasks()来获取任务列表。最后调用RecentTaskList的getTask方法

quickstep/src/com/android/quickstep/RecentTasksList.java/*** Asynchronously fetches the list of recent tasks, reusing cached list if available.** @param loadKeysOnly Whether to load other associated task data, or just the key* @param callback The callback to receive the list of recent tasks* @return The change id of the current task list*/public synchronized int getTasks(boolean loadKeysOnly,Consumer<ArrayList<GroupTask>> callback, Predicate<GroupTask> filter) {final int requestLoadId = mChangeId;...... 省略// Kick off task loading in the backgroundmLoadingTasksInBackground = true;UI_HELPER_EXECUTOR.execute(() -> {if (!mResultsBg.isValidForRequest(requestLoadId, loadKeysOnly)) {// 异步加载任务mResultsBg = loadTasksInBackground(Integer.MAX_VALUE, requestLoadId, loadKeysOnly);}TaskLoadResult loadResult = mResultsBg;mMainThreadExecutor.execute(() -> {mLoadingTasksInBackground = false;mResultsUi = loadResult;if (callback != null) {// filter the tasks if needed before passing them into the callbackArrayList<GroupTask> result = mResultsUi.stream().filter(filter).map(GroupTask::copy).collect(Collectors.toCollection(ArrayList<GroupTask>::new));callback.accept(result);}});});return requestLoadId;}

其中的loadTasksInBackground是真正加载任务数据的地方,代码如下:

quickstep/src/com/android/quickstep/RecentTasksList.java/*** Loads and creates a list of all the recent tasks.*/@VisibleForTestingTaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {int currentUserId = Process.myUserHandle().getIdentifier();// 获取最近任务数据ArrayList<GroupedRecentTaskInfo> rawTasks =mSysUiProxy.getRecentTasks(numTasks, currentUserId);// The raw tasks are given in most-recent to least-recent order, we need to reverse itCollections.reverse(rawTasks);SparseBooleanArray tmpLockedUsers = new SparseBooleanArray() {@Overridepublic boolean get(int key) {if (indexOfKey(key) < 0) {// Fill the cached locked state as we fetchput(key, mKeyguardManager.isDeviceLocked(key));}return super.get(key);}};TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());int numVisibleTasks = 0;...... 省略  数据加工处理return allTasks;}

接着又在SystemUiProxy的getRecentTasks方法中加载

quickstep/src/com/android/quickstep/SystemUiProxy.javapublic ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {if (mRecentTasks == null) {Log.w(TAG, "getRecentTasks() failed due to null mRecentTasks");return new ArrayList<>();}try {final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,RECENT_IGNORE_UNAVAILABLE, userId);if (rawTasks == null) {return new ArrayList<>();}return new ArrayList<>(Arrays.asList(rawTasks));} catch (RemoteException e) {Log.w(TAG, "Failed call getRecentTasks", e);return new ArrayList<>();}}

其中的关键代码是

quickstep/src/com/android/quickstep/SystemUiProxy.java
final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,RECENT_IGNORE_UNAVAILABLE, userId);

这里的mRecentTasks是private IRecentTasks mRecentTasks; IRecentTasks类型,这是wm提供的一个AIDL接口。所以,最终最近任务的数据是来自于wm。

核心流程概述:

Launcher 加载最近任务数据的流程是一个典型的分层异步带缓存的设计:

  1. UI 层 (RecentsView): 需要数据来展示,并发起请求。
  2. 模型层 (RecentsModel): 作为中间层,管理数据缓存(图标、缩略图)和数据源(任务列表),并处理数据更新和分发。
  3. 数据源层 (RecentTasksList): 负责直接与系统服务交互,获取原始的最近任务列表,并提供简单的缓存机制。

详细步骤:

  1. 触发加载 (Triggering Load) - RecentsView:

    • RecentsView 需要显示或刷新最近任务列表时(例如,进入概览状态 setOverviewStateEnabled(true) (line 1404),或者视图附加到窗口 onAttachedToWindow() (line 1080) 后调用 reloadIfNeeded() (line 2546)),它会检查当前数据是否需要更新。
    • reloadIfNeeded() 方法会调用 mModel.isTaskListValid(mTaskListChangeId) (line 2548) 来检查当前 RecentsView 持有的任务列表 ID 是否仍然有效。
    • 如果 ID 失效或从未加载过,它会调用 mModel.getTasks(this::applyLoadPlan, mFilterState) (line 2550) 来请求最新的任务数据。this::applyLoadPlan 是一个回调函数,当数据加载完成后会被执行。mFilterState 用于过滤任务。
  2. 请求传递 (Request Forwarding) - RecentsModel:

    • RecentsModelgetTasks(Consumer<ArrayList<GroupTask>> callback, Predicate<GroupTask> filter) 方法 (line 151, 165) 接收到来自 RecentsView 的请求。
    • 不会自己直接去获取系统数据,而是将请求进一步委托RecentTasksList 实例 (mTaskList),调用 mTaskList.getTasks(false /* loadKeysOnly */, callback, filter) (line 167)。它将 RecentsView 传来的回调函数和过滤器原样传递下去。
  3. 检查缓存与异步加载 (Cache Check & Async Loading) - RecentTasksList:

    • RecentTasksList.getTasks(...) (line 121) 首先检查其UI 线程缓存 (mResultsUi) 是否包含针对当前请求 ID (mChangeId) 的有效数据(并且满足 loadKeysOnly 的要求)。mChangeId 会在系统任务列表发生变化时递增。
    • 缓存命中 (Cache Hit): 如果 mResultsUi 有效,它会立即(通过 mMainThreadExecutor.post) 将缓存的数据(经过 filter 过滤和拷贝 map(GroupTask::copy)) 传递给 RecentsViewapplyLoadPlan 回调。加载流程快速结束。
    • 缓存未命中 (Cache Miss): 如果 mResultsUi 无效,说明需要从系统重新加载。
      • 它会将 mLoadingTasksInBackground 标记为 true
      • 它使用 UI_HELPER_EXECUTOR (后台线程池) 调度一个后台任务来加载数据。
      • 后台任务首先检查后台线程缓存 (mResultsBg) 是否有效。如果无效,它会调用 loadTasksInBackground(...) (line 232)。
      • loadTasksInBackground(...) 调用 mSysUiProxy.getRecentTasks(...) (line 236) 通过 Binder (IPC) 从 SystemUI(或其他系统服务)获取原始的 GroupedRecentTaskInfo 列表。
      • 获取到原始数据后,loadTasksInBackground 进行处理:
        • 反转列表顺序(系统返回的是最新->最旧,PagedView 需要最旧->最新)。
        • 遍历 GroupedRecentTaskInfo
        • 为每个任务创建 Task.TaskKey
        • 如果 loadKeysOnlyfalse,则创建完整的 Task 对象 (Task.from(...)),包含任务的详细信息。
        • 处理单任务和分屏任务对,并将它们包装成 GroupTaskDesktopTask 对象。
        • 将处理后的 ArrayList<GroupTask> 存储在 mResultsBg 中。
      • 后台任务完成后,它会将结果 (mResultsBg) 通过 mMainThreadExecutor.execute 发送回主线程
  4. 数据返回与 UI 更新 (Data Return & UI Update) - RecentTasksList -> RecentsModel -> RecentsView:

    • 回到主线程后,RecentTasksList 将后台加载的结果 (mResultsBg) 复制到 UI 线程缓存 (mResultsUi) (line 160)。
    • mLoadingTasksInBackground 标记为 false
    • 调用最初由 RecentsView 传入的回调函数(即 applyLoadPlan),并将经过 filter 过滤和拷贝的数据传递给它 (line 166)。
    • RecentsView.applyLoadPlan(ArrayList<GroupTask> taskGroups) (line 1666) 被执行:
      • 它清空当前的视图。
      • 遍历接收到的 taskGroups 列表。
      • 对于每个 GroupTask,它从视图池 (mTaskViewPool, mGroupedTaskViewPool, etc. line 507-509) 中获取或创建一个 TaskView (或其子类)。
      • 调用 taskView.bind(task, ...) 等方法,将 Task 对象中的数据(如应用名称、图标、缩略图占位符等)绑定到 TaskView 上。
      • 将填充好数据的 TaskView 添加到 RecentsView 中 (addView(tv) line 1788)。
      • 更新滚动范围、ClearAll 按钮状态等。
  5. 系统更新通知 (System Update Notification):

    • RecentTasksList 在初始化时通过 mSysUiProxy.registerRecentTasksListener(...) (line 76) 注册了一个监听器。
    • 当系统(如 SystemUI)中的最近任务列表发生变化时,会通过 Binder 回调 IRecentTasksListener.onRecentTasksChanged()
    • 这个回调被调度到主线程执行 RecentTasksList.this::onRecentTasksChanged (line 80)。
    • onRecentTasksChanged (line 185) 调用 invalidateLoadedTasks() (line 189),这会递增 mChangeId 并将 mResultsUimResultsBg 标记为无效。
    • 这保证了下一次 RecentsView 调用 reloadIfNeeded() 时,会触发一次新的数据加载流程,而不是使用过期的缓存。

总结:

Launcher 的最近任务加载是一个精心设计的流程,它通过 RecentsModel 解耦了 UI 和数据获取,利用 RecentTasksList 处理与系统的交互和基本缓存。通过异步加载避免阻塞 UI 线程,并通过 mChangeId 和系统回调确保数据在需要时能得到及时更新,同时利用缓存 (mResultsUi, mResultsBg) 提高了效率。图标和缩略图的加载/缓存则由 RecentsModel 中的 TaskIconCacheTaskThumbnailCache 独立处理,并通过 TaskVisualsChangeListener 接口将更新通知给 RecentsView

相关文章:

AOSP Android14 Launcher3——RecentsView最近任务数据加载

最近任务是Launcher中的一个重要的功能&#xff0c;显示用户最近使用的应用&#xff0c;并可以快速切换到其中的应用&#xff1b;用户可以通过底部上滑停顿进入最近任务&#xff0c;也可以在第三方应用底部上滑进最近任务。 这两种场景之前的博客也介绍过&#xff0c;本文就不…...

分析型数据库与事务型数据库?核心差异与选型指南

在当今数据驱动的业务环境中&#xff0c;选择合适的数据库架构已成为企业技术决策的关键。然而&#xff0c;面对事务型数据库和分析型数据库的选择&#xff0c;许多技术团队往往陷入困境&#xff1a;日常运行良好的系统在数据量激增时性能骤降&#xff0c;简单的查询在复杂分析…...

Linux-信号

信号是由用户&#xff0c;系统或者进程发送给目标进程的信息&#xff0c;以通知目标进程某个状态的改变或系统异常。 进程分为前台进程和后台进程&#xff0c;对于前台进程我们可以输入特殊的终端字符来给它发送信号&#xff0c;比如输入Ctrlc&#xff0c;发送一个中断信号 系…...

Oracle数据库学习之路-目录

Oracle数据库学习之路 一、安装 &#xff08;一&#xff09;数据库安装步骤详解 &#xff08;二&#xff09;开发工具安装与配置 二、基础语法篇 &#xff08;一&#xff09;基础 SQL 语法详解 &#xff08;二&#xff09;SQL 语法练习与案例分析 三、高级语法篇 &…...

用selenium4 webdriver + java 搭建并完成第一个自动化测试脚本

自动化测试任务&#xff1a; 百度搜索自己的姓名。点击第一个链接&#xff08;或者第二个&#xff09;&#xff0c;在新的页面上&#xff0c;添加断言&#xff0c;验证你的名字是否存在。 实验资料百度网盘下载路径&#xff1a; 链接: https://pan.baidu.com/s/1nVlHX_ivres…...

晨控CK-FR12与欧姆龙NX系列PLC配置EtherNet/IP通讯连接操作手册

晨控CK-FR12系列作为晨控智能工业级别RFID读写器,支持大部分工业协议如RS232、RS485、以太网。支持工业协议Modbus RTU、Modbus TCP、Profinet、EtherNet/lP、EtherCat以及自由协议TCP/IP等。 本期主题&#xff1a;围绕CK-FR12产品的EtherNet/IP通讯协议与欧姆龙PLC进行通讯配置…...

武装Burp Suite工具:RouteVulScan插件_被动扫描发现漏洞.

武装Burp Suite工具&#xff1a;RouteVulScan插件_被动扫描. RouteVulScan 是一款使用Java语言编写&#xff0c;基于Burp Suite API的插件&#xff0c;用于递归地检测潜在的脆弱路径。 该插件通过被动扫描的方式&#xff0c;对路径的各个层级进行深度分析。利用预设的正则表达…...

Selenium+Java 环境搭建

windows电脑环境搭建Chrome浏览器 1.下载 Google Chrome 网络浏览器 &#xff08;一定要下载官方的&#xff01;&#xff01;&#xff01;&#xff09; 注&#xff1a;最好下载在浏览器默认的路径 便于查找&#xff0c;而且占内存不是很大 2.查看chrome浏览器的版本 3.下载…...

网易云IP属地可以查看城市吗?深度解析与使用指南

在互联网时代&#xff0c;用户的隐私和数据安全越来越受到关注。许多社交平台和应用都会显示用户的IP属地&#xff0c;以增加透明度和真实性。网易云音乐作为国内领先的音乐平台&#xff0c;也引入了IP属地显示功能。那么&#xff0c;网易云IP属地能否精确到城市&#xff1f;这…...

Cline 之Plan和Act模式

Cline 提供了 "Plan & Act"双模式开发框架。适用在不同的场景。 一、核心模式理念 通过结构化开发流程提升AI编程效率&#xff0c;采用"先规划后执行"的核心理念。 该框架旨在帮助开发者构建更易维护、准确性更高的代码&#xff0c;同时显著缩短开发…...

【Java面试笔记:基础】7.int和Integer有什么区别?

在Java中&#xff0c;int和Integer虽然都用于表示整数值&#xff0c;但它们在本质、用法和特性上有显著差异。 1. int 和 Integer 的区别 int&#xff1a; 原始数据类型&#xff1a;int 是 Java 的 8 个原始数据类型之一&#xff0c;用于表示整数。性能优势&#xff1a;直接存…...

嘻游后台系统与机器人模块结构详解:功能逻辑 + 定制改造实战

作为“嘻游电玩三端组件”系列的最后一篇&#xff0c;本篇将全面剖析平台自带的后台控制系统与机器人行为逻辑模块&#xff0c;包括&#xff1a;用户管理、房间配置、日志系统、机器人规则编排与行为策略扩展等。通过技术视角展示其整体框架与可拓展性&#xff0c;帮助开发者更…...

Linux 网络编程:select、poll 与 epoll 深度解析 —— 从基础到高并发实战

一、IO 多路复用&#xff1a;解决并发 IO 的核心技术 在网络编程中&#xff0c;当需要同时处理大量客户端连接时&#xff0c;传统阻塞式 IO 会导致程序卡在单个操作上&#xff0c;造成资源浪费。IO 多路复用技术允许单线程监听多个文件描述符&#xff08;FD&#xff09;&#…...

在统信UOS1060上安装Fail2Ban并通过邮件发送通知

在统信UOS1060上安装Fail2Ban并通过邮件发送通知 Fail2Ban 是一个开源的防止暴力攻击的软件&#xff0c;可以有效保护您的服务器免受频繁的登录失败攻击。本文将指导您如何在统信UOS 1060上安装Fail2Ban&#xff0c;并在IP被封禁后通过邮件发送通知。 步骤 1&#xff1a;查看…...

PyTorch 分布式 DistributedDataParallel (DDP)

在之前的讨论&#xff08;或者如果你直接跳到这里&#xff09;中&#xff0c;我们了解了 torch.nn.DataParallel (DP) 作为 PyTorch 多 GPU 训练的入门选项。它简单易用&#xff0c;但其固有的主 GPU 瓶颈、GIL 限制和低效的通信模式&#xff0c;往往让它在实际应用中难以充分发…...

精益数据分析(14/126):基于数据洞察优化产品与运营

精益数据分析&#xff08;14/126&#xff09;&#xff1a;基于数据洞察优化产品与运营 在创业和数据分析的道路上&#xff0c;我们都在不断摸索前行。我一直希望能和大家共同学习、共同进步&#xff0c;所以今天继续为大家解读《精益数据分析》。这次我们将深入探讨HighScore …...

flutter 插件收集

2025年 1月10号Flutter插件手机 声音转文字 speech_to_text | Flutter package 文字转声音 flutter_tts | Flutter package 堆栈信息 stack_trace | Dart package 跳转到app设置里面 app_settings | Flutter package 轻松的动画 animations | Flutter package 日志打印 t…...

WPF特性分析

文章目录 WPF特性全面分析与性能优化指南引言WPF核心特性1. 声明式UI与XAML2. 硬件加速渲染3. 数据绑定与MVVM4. 样式与模板5. 动画系统 WPF与其他框架比较WPF vs. WinFormsWPF vs. UWPWPF vs. MAUI WPF性能优化最佳实践1. 内存管理优化2. UI虚拟化3. 使用冻结对象4. 减少视觉树…...

3.1goweb框架gin下

Gin 框架有内置的模板引擎&#xff0c;它允许你将数据和 HTML 模板结合&#xff0c;动态生成网页内容。 模板引擎基础使用 单模板文件示例 以下是一个简单的使用单个 HTML 模板文件的示例&#xff0c;展示了如何在 Gin 中渲染模板&#xff1a; package mainimport ("g…...

【全解析】深入理解 JavaScript JSON 数据解析

一、JSON 概述 1. 概念 JSON 全称为 JavaScript Object Notation&#xff0c;是一种轻量级的数据交换格式。它是 JavaScript 中用于描述对象数据的语法的扩展。不过并不限于与 JavaScript 一起使用。它采用完全独立于语言的文本格式&#xff0c;这些特性使 JSON 成为理想的数…...

影刀RPA怎么和AI结合,制作自动采集小红书爆款文章+自动用AI改写标题、内容+用AI文生图生成发文图片+自动在小红书上发布文章

环境: 影刀5.26.24 Win10专业版 doubao deepseek r1 wps 问题描述: 影刀RPA怎么和AI结合,制作自动采集小红书爆款文章+自动用AI改写标题、内容+用AI文生图生成发文图片+自动在小红书上发布文章,最后上传到飞书备份 解决方案: 1.主要流程如下: 全局变量设置(关键…...

懒人一键搭建符号执行环境V5K3

0.背景 在写完上一篇文章后发现&#xff0c;其实V5k3的组合也可以使用。Verilator v5.x 系列版本完全支持本项目的编译与仿真。 不同于 v3 版本&#xff0c;Verilator v5 引入了更严格的访问控制机制&#xff1a;要从 Verilator 生成的 C 仿真模型中访问内部信号或变量&#x…...

Java队列(Queue)核心操作与最佳实践:深入解析与面试指南

文章目录 概述一、Java队列核心实现类对比1. LinkedList2. ArrayDeque3. PriorityQueue 二、核心操作API与时间复杂度三、经典使用场景与最佳实践场景1&#xff1a;BFS层序遍历&#xff08;树/图&#xff09;场景2&#xff1a;滑动窗口最大值&#xff08;单调队列&#xff09; …...

Android 中实现图片翻转动画(卡片翻转效果)

1、简述 通过 ObjectAnimator 和 AnimatorSet 可以实现图片的翻转动画,并在翻转过程中切换图片,同时避免图片被镜像。 ObjectAnimator 是 Android 动画框架中的一个类,用于对对象的属性进行动画效果处理。它通过改变对象的属性值来实现动画效果,非常适合实现复杂的动画,如…...

智能电网第1期 | 工业交换机在变电站自动化系统中的作用

随着智能电网建设的加速推进&#xff0c;变电站自动化系统对通信网络的实时性、可靠性和安全性提出了更高要求。在变电站智能化改造过程中&#xff0c;传统网络架构面临诸多挑战&#xff1a; 多协议兼容难题&#xff1a;继电保护、测控装置等设备通信协议多样&#xff0c;难以统…...

01.浏览器自动化webdriver源码分析之启动函数

日后&#xff0c;网络爬虫也好&#xff0c;数据采集也好&#xff0c;自动化必然是主流。因此&#xff0c;笔者未雨绸缪&#xff0c;在此研究各类自动化源码&#xff0c;希望能够赶上时代&#xff0c;做出一套实用的自动化框架。 这里先研究传统的webdriver中转来进行浏览器自动…...

day35图像处理OpenCV

文章目录 一、图像预处理17 直方图均衡化17.1绘制直方图17.2直方图均衡化1. 自适应直方图均衡化2. 对比度受限的自适应直方图均衡化3. 示例 19 模板匹配 一、图像预处理 17 直方图均衡化 直方图&#xff1a;反映图像像素分布的统计图&#xff0c;横坐标就是图像像素的取值&…...

精益数据分析(15/126):解锁数据分析关键方法,驱动业务增长

精益数据分析&#xff08;15/126&#xff09;&#xff1a;解锁数据分析关键方法&#xff0c;驱动业务增长 在创业与数据分析的征程中&#xff0c;我们都在努力探寻成功的密码。今天&#xff0c;我依旧带着和大家共同进步的初衷&#xff0c;深入解读《精益数据分析》的相关内容…...

JETBRAINS USER AGREEMENT【2025.4.16】更新用户许可协议

JETBRAIN旗下的各产品更新用户许可协议&#xff1a; 大致跟漂亮国出口管制政策有关&#xff0c;以下是详细内容&#xff1a; JETBRAINS USER AGREEMENT Version 2.0, effective as of April 16, 2025 THIS IS A LEGAL AGREEMENT. BY CLICKING ON THE "I AGREE" (OR…...

【数字图像处理】立体视觉基础(1)

成像 成像过程&#xff1a;三维空间坐标到二维图像坐标的变换 相机矩阵&#xff1a;建立三维到二维的投影关系 相机的使用步骤&#xff08;模型-视图变换&#xff09;&#xff1a; &#xff08;1&#xff09;视图变换 &#xff08;2&#xff09;模型变换 &#xff08;3&…...

通过AI工具或模型创建PPT的不同方式详解,结合 Assistants API、DALL·E 3 等工具的功能对比及表格总结

以下是通过AI工具或模型创建PPT的不同方式详解&#xff0c;结合 Assistants API、DALLE 3 等工具的功能对比及表格总结&#xff1a; 1. 主要实现方式详解 1.1 基于文本生成PPT 工具示例&#xff1a;Microsoft PowerPoint Copilot、Google Workspace&#xff08;AI-powered D…...

weibo_har鸿蒙微博分享,单例二次封装,鸿蒙微博,微博登录

weibo_har鸿蒙微博分享&#xff0c;单例二次封装&#xff0c;鸿蒙微博 HarmonyOS 5.0.3 Beta2 SDK&#xff0c;原样包含OpenHarmony SDK Ohos_sdk_public 5.0.3.131 (API Version 15 Beta2) &#x1f3c6;简介 zyl/weibo_har是微博封装使用&#xff0c;支持原生core使用 &a…...

C++ Lambda表达式复习

C Lambda表达式 (C Lambda Expressions: Beginner to Advanced) Lambda表达式是C11引入的一种轻量级匿名函数语法&#xff0c;支持闭包捕获&#xff0c;可以简化代码逻辑&#xff0c;特别是在函数式编程、回调函数和STL算法场景中尤为常用。本文将从基础语法到高级应用&#x…...

鸿蒙NEXT开发权限工具类(申请授权相关)(ArkTs)

import abilityAccessCtrl, { Permissions } from ohos.abilityAccessCtrl; import { bundleManager, common, PermissionRequestResult } from kit.AbilityKit; import { BusinessError } from ohos.base; import { ToastUtil } from ./ToastUtil;/*** 权限工具类&#xff08;…...

1000 QPS 下 MySQL 性能瓶颈解决方案

当 MySQL 在 1000 QPS 时出现性能瓶颈&#xff0c;需从‌索引优化‌、‌查询逻辑调整‌、‌服务器配置调优‌、‌架构扩展‌等多维度综合解决&#xff0c;具体策略如下&#xff1a; 一、索引优化 补充缺失索引‌ 通过慢查询日志定位高频低效 SQL&#xff0c;使用 EXPLAIN 分…...

【MySQL】MySQL 表的增删改查(CRUD)—— 下篇(内含聚合查询、group by和having子句、联合查询、插入查询结果)

目录 1. 插入查询结果 2 聚合查询 &#xff08;行与行之间运算&#xff09; count 计算查询结果的行数 sum 求和 avg 求平均值 max 最大值 min 最小值 【小结】 3. group by 子句 分组 where 条件 having 条件 4. 联合查询&#xff08;多表查询&#xff09; 内连接…...

简化K8S部署流程:通过Apisix实现蓝绿发布策略详解(上)

本次主题主要目的是为大家讲解蓝绿发布&#xff0c;但是发现文档和内容太长了&#xff0c;对此将文档拆分成了两部分&#xff0c;视频拆分成了好几部分&#xff0c;这样大家刷起来没疲劳感。 第一部分《apisix argorollout 实现蓝绿发布I-使用apisix发布应用》&#xff0c;主要…...

FLV 与 MP4 格式深度剖析:结构、原理

1 FLV格式分析 1.1 定义 FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式&#xff0c;由于其封装后的⾳视频⽂件体积⼩、封装简单等特点&#xff0c;⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤FLV格式封装的⽂件后缀为.flv FLV封装格式是由⼀个**⽂件…...

k8s的yaml文件里的volume跟volumeMount的区别

volume 是 Pod 级别的资源&#xff0c;用于定义存储卷。它是一个独立于容器的存储资源&#xff0c;可以被一个或多个容器共享使用。volume 的定义位于 Pod 的 spec.volumes 部分。 特点 独立性&#xff1a;volume 是 Pod 的一部分&#xff0c;而不是容器的一部分。它独立于容…...

Git常用操作命令

配置 Git git config --global user.name "Your Name": 设置用户名。git config --global user.email "your_emailexample.com": 设置用户邮箱。 初始化和克隆仓库 git init: 初始化一个新的 Git 仓库。git clone [URL]: 克隆一个远程仓库到本地。 git cl…...

09.传输层协议 ——— TCP协议

文章目录 TCP协议 谈谈可靠性TCP协议格式 序号与确认序号窗口大小六个标志位 确认应答机制&#xff08;ACK&#xff09;超时重传机制连接管理机制 三次握手四次挥手 流量控制滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP的应用层协议 TCP协…...

NineData 与飞书深度集成,企业级数据管理审批流程全面自动化

NineData 正式推出与飞书审批系统的深度集成功能&#xff0c;企业用户在 NineData 平台发起的审批工单&#xff0c;将自动推送至审批人的飞书中&#xff0c;审批人可以直接在飞书进行审批并通过/拒绝。该功能实现跨系统协作&#xff0c;带来巨大的审批效率提升&#xff0c;为各…...

WebRTC服务器Coturn服务器中的通信协议

1、概述 作为WebRTC服务器&#xff0c;coturn通信协议主要是STUN和TURN协议 STUN&TURN协议头部都是20个字节,用 Message Type来区分不同的协议 |------2------|------2------|------------4------------|------------------------12-------------------------|-----------…...

4.19除自身以外数组的乘积

我自己的思路&#xff0c;想用双指针&#xff0c; 一个从左边left开始乘&#xff0c;一个从右边right开始乘&#xff0c;如果left,或者right遇到了目标索引i(也就是我们要跨过去的当前元素)&#xff0c;那么直接让对应的指针加一&#xff0c;当前元素不参与累积的计算&#xff…...

Anaconda3使用conda进行包管理

一、基础包管理操作 ‌安装包‌ 使用 conda install <包名> 安装指定包&#xff0c;支持多包批量安装和版本指定&#xff1a; conda install numpy # 安装单个包 conda install numpy scipy pandas # 批量安装多个包 conda install numpy1.21 # 指定版本 conda instal…...

媒体关注:联易融聚焦AI+业务,重塑供应链金融生态

近日&#xff0c;供应链金融科技龙头企业联易融科技集团&#xff08;以下简称“联易融”&#xff09;发布的公告显示&#xff0c;截至2024年末&#xff0c;公司现金储备达51亿元&#xff0c;同比上一年增加2亿元。公司称&#xff0c;公司经营性现金流保持健康&#xff0c;现金储…...

安装 Conda 环境

安装 Conda 环境&#xff1a;快速指南 什么是 Conda&#xff1f; Conda 是一个开源的跨平台包管理器和环境管理系统&#xff0c;支持 Python、R、Julia 等语言。它广泛用于数据科学和机器学习领域&#xff0c;能够轻松创建、管理和切换开发环境。 安装步骤 1. 安装 Anaconda…...

Qt Creator 创建 Qt Quick Application一些问题

一、Qt Creator 创建 Qt Quick Application 时无法选择 MSVC 编译器(即使已安装 Qt 5.15.2 和 MSVC2019) 1、打开 Qt Creator 的编译器设置 工具 (Tools) → 选项 (Options) → Kits → 编译器 (Compilers) 检查是否存在 Microsoft Visual C++ Compiler (x86_amd64) 或类似条…...

Spark-Streaming核心编程

以下是今天所学的知识点与代码测试&#xff1a; Spark-Streaming DStream实操 案例一&#xff1a;WordCount案例 需求&#xff1a;使用 netcat 工具向 9999 端口不断的发送数据&#xff0c;通过 SparkStreaming 读取端口数据并统计不同单词出现的次数 实验步骤&#xff1a;…...

深度剖析神经网络:从基础原理到面试要点(二)

引言 在人工智能蓬勃发展的今天&#xff0c;神经网络作为其核心技术之一&#xff0c;广泛应用于图像识别、自然语言处理、语音识别等众多领域。深入理解神经网络的数学模型和结构&#xff0c;对于掌握人工智能技术至关重要。本文将对神经网络的关键知识点进行详细解析&#xf…...