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

Android audio(6)-audiopolicyservice介绍

AudioPolicyService 是策略的制定者,比如某种 Stream 类型不同设备的音量(index/DB)是多少、某种 Stream 类型的音频数据流对应什么设备等等。而 AudioFlinger 则是策略的执行者,例如具体如何与音频设备通信,维护现有系统中可用的音频设备,以及多个音频流的混音处理,音频数据流的算法处理(重采样,音效),音量调节,音频数据搬运等等都由它完成。

AudioPolicyService 根据用户配置来指导 AudioFlinger 加载设备接口,起到路由功能。在 Android Audio 系统中主要完成以下几个任务:
1)管理输入输出设备,包括设备的连接/断开状态,设备的选择和切换等
2)管理系统的音频策略,比如通话时播放音乐、或者播放音乐时来电话的一系列处理
3)管理系统的音量/静音
4)上层的一些音频参数也可以通过AudioPolicyService设置到底层
5)管理音效和流的配置

一、初始化

与AudioPolicyService 生命周期关联的有三个函数, 构造函数 AudioPolicyService、onFirstRef 和初始化有关, 析构函数 ~AudioPolicyService 和销毁有关。通过对android代码的学习,我们可以看到与成员变量相关的初始化都是 在构造函数里面做,而与业务相关的初始化都是在onFirstRef 里面完成。这是关注点分离思想的一种体现。

源码位置:/frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp

1、构造函数

AudioPolicyService::AudioPolicyService(): BnAudioPolicyService(), // 定义在IAudioPolicyService.h中, 作为Binder调用的Bn端mAudioPolicyManager(NULL),  // APMmAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID), // 通话状态 mCaptureStateNotifier(false) {
}

2、onFirstRef

void AudioPolicyService::onFirstRef()
{{Mutex::Autolock _l(mLock);//一个系统的服务通常都需要线程去承载,不断处理命令。// 启动音频命令线程,audio命令相关,如音量控制、音频参数设置mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);// 启动输出命令线程,Output管理mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);mAudioPolicyClient = new AudioPolicyClient(this);mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);}sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();sp<UidPolicy> uidPolicy = new UidPolicy(this);sp<SensorPrivacyPolicy> sensorPrivacyPolicy = new SensorPrivacyPolicy(this);{Mutex::Autolock _l(mLock);mAudioPolicyEffects = audioPolicyEffects;mUidPolicy = uidPolicy;mSensorPrivacyPolicy = sensorPrivacyPolicy;}uidPolicy->registerSelf();sensorPrivacyPolicy->registerSelf();
}

可以看到这里创建了两个 AudioCommandThread 和 AudioPolicyManager,而在创建 AudioPolicyManager 时创建了AudioPolicyClient作为参数传入其中。

3、析构函数

AudioPolicyService::~AudioPolicyService()
{mAudioCommandThread->exit();mOutputCommandThread->exit();destroyAudioPolicyManager(mAudioPolicyManager);delete mAudioPolicyClient;mNotificationClients.clear();mAudioPolicyEffects.clear();mUidPolicy->unregisterSelf();mSensorPrivacyPolicy->unregisterSelf();mUidPolicy.clear();mSensorPrivacyPolicy.clear();
}

这里主要是做销毁,情基本是对初始化创建对象的回收。

二、AudioPolicyManager

AudioPolicyManager是 AudioPolicyService 服务进程下的功能模块,主要负责解析各种 Audio 配置 xml 文件,例如 audio_policy_configuration.xml 中音频的设备、流以及路由关系等。从audiopolicyservice和audiopolicymanager的设计我们可以学到,服务承载实体(进程,service等)可以和服务的业务逻辑代码分离!!!!! 服务实体是为了实现异步以及序列化操作

1、AudioPolicyManager创建
上面的代码可以看到 AudioPolicyManager 是在 AudioPolicyService 的 onFirstRef 中调用 createAudioPolicyManager() 方法创建的。传入参数为 new AudioPolicyClient(this)。这样audiopolicymanager就可以调用audiopolicyservice的接口。

createAudioPolicyManager

源码位置:/frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp

extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
{AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);status_t status = apm->initialize();if (status != NO_ERROR) {delete apm;apm = nullptr;}return apm;
}

AudioPolicyClient
AudioPolicyClient 类定义在 AudioPolicyService.h 中。源码位置:/frameworks/av/services/audiopolicy/service/AudioPolicyService.h

class AudioPolicyClient : public AudioPolicyClientInterface
{
public:
explicit AudioPolicyClient(AudioPolicyService *service) : mAudioPolicyService(service) {}

}

它的实现在 frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp 中。

AudioPolicyManager

源码位置:/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface, bool /*forTesting*/):mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.mpClientInterface(clientInterface),mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),mA2dpSuspended(false),mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice),mAudioPortGeneration(1),mBeaconMuteRefCount(0),mBeaconPlayingRefCount(0),mBeaconMuted(false),mTtsOutputAvailable(false),mMasterMono(false),mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
}AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface): AudioPolicyManager(clientInterface, false /*forTesting*/)
{loadConfig();
}void AudioPolicyManager::loadConfig() {// 处理音频配置xmlif (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {ALOGE("无法加载音频策略配置文件,设置默认值");getConfig().setDefault();}
}

对于解析音频配置相关的 xml 文件我们会在后面单独分析。

三、Engine创建

Engine 是主要负责音频路由/音量相关的业务。Engine 的创建是在 AudioPolicyManager 的 initialize() 中。

status_t AudioPolicyManager::initialize() {{auto engLib = EngineLibrary::load("libaudiopolicyengine" + getConfig().getEngineLibraryNameSuffix() + ".so");……mEngine = engLib->createEngine();……mEngine->setObserver(this);status_t status = mEngine->initCheck();……}……return status;
}

EngineLibrary.cpp:createEngine
源码位置:/frameworks/av/services/audiopolicy/managerdefault/EngineLibrary.cpp

bool EngineLibrary::init(std::string libraryPath)
{……mCreateEngineInstance = (EngineInterface* (*)())dlsym(mLibraryHandle, "createEngineInstance");……return true;}EngineInstance EngineLibrary::createEngine()
{if (mCreateEngineInstance == nullptr || mDestroyEngineInstance == nullptr) {return EngineInstance();}return EngineInstance(mCreateEngineInstance(),[lib = shared_from_this(), destroy = mDestroyEngineInstance] (EngineInterface* e) {destroy(e);});
}

EngineInstance .cpp:createEngineInstance
源码位置:/frameworks/av/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp

EngineInstance *EngineInstance::getInstance()
{static EngineInstance instance;return &instance;
}Engine *EngineInstance::getEngine() const
{static Engine engine;return &engine;
}template <>
EngineInterface *EngineInstance::queryInterface() const
{return getEngine()->queryInterface<EngineInterface>();
}extern "C" EngineInterface* createEngineInstance()
{return audio_policy::EngineInstance::getInstance()->queryInterface<EngineInterface>();
}

在这里最后创建了 Engine。
Engine.cpp
源码位置:/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

Engine::Engine()
{auto result = EngineBase::loadAudioPolicyEngineConfig();auto legacyStrategy = getLegacyStrategy();for (const auto &strategy : legacyStrategy) {mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;}
}

这里调用了一个比较重要的函数 loadAudioPolicyEngineConfig()。

EngineBase.cpp: loadAudioPolicyEngineConfig()

engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
{auto loadVolumeConfig = [](auto &volumeGroups, auto &volumeConfig) {// 确保名称唯一LOG_ALWAYS_FATAL_IF(std::any_of(std::begin(volumeGroups), std::end(volumeGroups), [&volumeConfig](const auto &volumeGroup) {return volumeConfig.name == volumeGroup.second->getName(); }), "group name %s defined twice, review the configuration", volumeConfig.name.c_str());// 表示当前VolumeGroup还没有被加载过,开始创建加载sp<VolumeGroup> volumeGroup = new VolumeGroup(volumeConfig.name, volumeConfig.indexMin, volumeConfig.indexMax);volumeGroups[volumeGroup->getId()] = volumeGroup;for (auto &configCurve : volumeConfig.volumeCurves) {device_category deviceCat = DEVICE_CATEGORY_SPEAKER;if (!DeviceCategoryConverter::fromString(configCurve.deviceCategory, deviceCat)) {continue;}sp<VolumeCurve> curve = new VolumeCurve(deviceCat);for (auto &point : configCurve.curvePoints) {curve->add({point.index, point.attenuationInMb});}volumeGroup->add(curve);}return volumeGroup;};auto addSupportedAttributesToGroup = [](auto &group, auto &volumeGroup, auto &strategy) {for (const auto &attr : group.attributesVect) {strategy->addAttributes({group.stream, volumeGroup->getId(), attr});volumeGroup->addSupportedAttributes(attr);}};auto checkStreamForGroups = [](auto streamType, const auto &volumeGroups) {const auto &iter = std::find_if(std::begin(volumeGroups), std::end(volumeGroups), [&streamType](const auto &volumeGroup) {const auto& streams = volumeGroup.second->getStreamTypes();return std::find(std::begin(streams), std::end(streams), streamType) != std::end(streams);});return iter != end(volumeGroups);};// 这里开始进行解析,最终会解析出来策略、标准、标准类型以及音量组四个内容auto result = engineConfig::parse();if (result.parsedConfig == nullptr) {// 如果上面没有解析没有找到配置,使用默认的配置engineConfig::Config config = gDefaultEngineConfig;android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);result = {std::make_unique<engineConfig::Config>(config), static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};}……engineConfig::VolumeGroup defaultVolumeConfig;engineConfig::VolumeGroup defaultSystemVolumeConfig;// 循环解析所有的音量组for (auto &volumeConfig : result.parsedConfig->volumeGroups) {// 保存未在配置中定义的流的默认音量配置 将music和patch作为未定义流类型的默认配置if (volumeConfig.name.compare("AUDIO_STREAM_MUSIC") == 0) {defaultVolumeConfig = volumeConfig;}if (volumeConfig.name.compare("AUDIO_STREAM_PATCH") == 0) {defaultSystemVolumeConfig = volumeConfig;}// 这里调用上面第一个lamabda表达式// 这里定义的mVolumeGroups是一个map容器,其中second是VolumeGroup指针,定义在VolumeGroup.h中// 这里调用这个lambda表达式是为了讲volumeConfig中包含的volumeGroups解析到mVolumeGroups中loadVolumeConfig(mVolumeGroups, volumeConfig);}// 循环遍历所有的音频策略for (auto& strategyConfig : result.parsedConfig->productStrategies) {sp<ProductStrategy> strategy = new ProductStrategy(strategyConfig.name);// 查找该策略是否有相应的音量组for (const auto &group : strategyConfig.attributesGroups) {const auto &iter = std::find_if(begin(mVolumeGroups), end(mVolumeGroups), [&group](const auto &volumeGroup) {return group.volumeGroup == volumeGroup.second->getName(); });sp<VolumeGroup> volumeGroup = nullptr;// 如果没有为此策略提供音量组,则使用音乐音量组配置创建一个新的音量组(视为默认设置) if (iter == end(mVolumeGroups)) {engineConfig::VolumeGroup volumeConfig;if (group.stream >= AUDIO_STREAM_PUBLIC_CNT) {volumeConfig = defaultSystemVolumeConfig;} else {volumeConfig = defaultVolumeConfig;}volumeConfig.name = group.volumeGroup;volumeGroup = loadVolumeConfig(mVolumeGroups, volumeConfig);} else {volumeGroup = iter->second;}if (group.stream != AUDIO_STREAM_DEFAULT) {// 可以将旧流一次分组 LOG_ALWAYS_FATAL_IF(checkStreamForGroups(group.stream, mVolumeGroups), "stream %s already assigned to a volume group, " "review the configuration", toString(group.stream).c_str());volumeGroup->addSupportedStream(group.stream);}// 为策略添加相应的属性addSupportedAttributesToGroup(group, volumeGroup, strategy);}product_strategy_t strategyId = strategy->getId();mProductStrategies[strategyId] = strategy;}// 将新创建的strategy保存到mProductStrategies中并分配一个单独的IDmProductStrategies.initialize();return result;
}

总结

通过前面几篇文章的学习,我们也了解了音频服务初始化的大致流程,下面总结一下:

audioserver实例化audioflinger
audioserver实例化audiopolicyservice
audiopolicyservice创建audiopolicymanager
audiopolicymanager解析xml配置文件
audiopolicymanager创建engine
audiopolicymanager调用audioflinger接口打开audio interface
audiopolicymanager调用audioflinger接口打开音频通道(output,注意区分stream和output的概念)

经过上面的流程系统音频服务已经启动处于ready状态,如果有应用需要播放则会通过服务选择合适的硬件播出。

相关文章:

Android audio(6)-audiopolicyservice介绍

AudioPolicyService 是策略的制定者&#xff0c;比如某种 Stream 类型不同设备的音量&#xff08;index/DB&#xff09;是多少、某种 Stream 类型的音频数据流对应什么设备等等。而 AudioFlinger 则是策略的执行者&#xff0c;例如具体如何与音频设备通信&#xff0c;维护现有系…...

【区块链安全 | 第三十八篇】合约审计之获取私有数据(二)

文章目录 前言漏洞代码代码审计攻击步骤修复/开发建议审计思路 前言 在【区块链安全 | 第三十七篇】合约审计之获取私有数据&#xff08;一&#xff09;中&#xff0c;介绍了私有数据、访问私有数据实例、Solidity 中的数据存储方式等知识&#xff0c;本文通过分析具体合约代码…...

muduo:运行起来

Muduo 概述 Muduo 是一个用 C 编写的高性能网络库&#xff0c;由陈硕开发&#xff0c;主要用于开发 Linux 环境下的高性能网络应用程序。以下从几个方面对其进行详细介绍&#xff1a; 特点 事件驱动与非阻塞 I/O&#xff1a;Muduo 基于 Reactor 模式实现&#xff0c;使用了 …...

算法篇(八)【递归】

一、了解递归 1. 什么是递归&#xff1f; 递归就是自己调用自己 递归的概念解释起来就短短的几句话&#xff0c;但是写起来总是无从下手 &#xff0c;但是首先要相信&#xff0c;在学过了数据结构 -- 树 之后 &#xff0c; 其实就已经具备了一定的递归思想&#xff0c;接下来的…...

Linux 学习笔记(4):cd 与 pwd 命令的深度解析与实战应用(期末、期中复习必备)

前言 一、cd 命令&#xff1a;切换工作目录的利器 1.命令来源与基本语法 2.命令使用示例 3.相对路径与绝对路径的使用 二、pwd 命令&#xff1a;清晰定位当前工作目录 1.命令来源与基本语法 2.命令使用示例 三、结语 前言 在 Linux 系统的操作中&#xff0c;对工作目录的…...

眨眼睛查看密码工具类

“眨眼睛查看密码”工具类实现思路&#xff1a; 一、核心功能 实现点击眼睛图标切换密码明文/星号显示&#xff0c;提升表单输入体验。包含以下关键功能&#xff1a; • 初始状态&#xff1a;密码框显示为星号&#xff0c;闭眼图标可见。 • 点击闭眼图标&#xff1a;切换为明…...

【嵌入式系统设计师】知识点:第9章 嵌入式系统安全性基础知识

提示:“软考通关秘籍” 专栏围绕软考展开,全面涵盖了如嵌入式系统设计师、数据库系统工程师、信息系统管理工程师等多个软考方向的知识点。从计算机体系结构、存储系统等基础知识,到程序语言概述、算法、数据库技术(包括关系数据库、非关系型数据库、SQL 语言、数据仓库等)…...

find指令中使用正则表达式

linux查找命令能结合正则表达式吗 find命令要使用正则表达式需要结合-regex参数 另&#xff0c;-type参数可以指定查找类型(f为文件&#xff0c;d为文件夹) rootlocalhost:~/regular_expression# ls -alh 总计 8.0K drwxr-xr-x. 5 root root 66 4月 8日 16:26 . dr-xr-…...

【RH124】第六章 管理本地用户和组

系列文章目录 第一章 红帽企业Linux入门 第二章 访问命令行 第三章 从命令行管理文件 第五章 创建、查看文本文件 第六章 管理本地用户和组 文章目录 系列文章目录前言一、用户和组1、用户2、组 二、获取超级用户访问权限1、root用户2、切换用户账户3、sudo配置 三、管理本地用…...

Linux学习笔记——中断

中断 硬中断和软中断的定义与区别硬中断&#xff08;Hardware Interrupt&#xff09;软中断&#xff08;Software Interrupt&#xff09; 硬中断与软中断的区别总结上半部和下半部机制详解为什么要分为上半部和下半部&#xff1f;上半部下半部 下半部的三种实现机制Linux中断响…...

Linux 进程间通信:信号机制

Linux 进程间通信&#xff1a;信号机制 在多进程操作系统中&#xff0c;进程之间的通信至关重要&#xff0c;尤其是在Linux系统中&#xff0c;信号&#xff08;Signal&#xff09;作为一种特殊的进程间通信方式&#xff0c;广泛用于进程之间的协调和控制。信号可以看作是操作系…...

计算机控制系统:arduino控制无源滤波器播放音乐

1 电脑播放简单音节 播放哆瑞咪发嗦啦西 在音频处理领域&#xff0c;声音合成是通过计算机算法模拟人类声音的一种技术。具体来说&#xff0c;模拟哆瑞咪发嗦啦西音节需要声卡先接收基本音符的信号&#xff0c;然后通过数字信号处理技术&#xff0c;将该信号转换为模拟声音输出…...

FTP协议和win server2022安装ftp

FTP协议简介 FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09;是一种用于在网络上的计算机之间传输文件的标准网络协议。它被广泛应用于服务器与客户端之间的文件上传、下载以及管理操作。FTP支持多种文件类型和结构&#xff0c;并提供了相对简单的…...

UNet 改进(4):融合Ghost Module的轻量化分割网络

引言 在计算机视觉领域,U-Net因其优秀的性能在图像分割任务中广受欢迎。 随着模型复杂度的增加,计算资源和内存消耗也大幅上升。 本文将介绍一种改进的U-Net架构,通过引入Ghost Module来实现模型的轻量化,同时保持分割性能。 代码概述 这个实现构建了一个基于U-Net架构…...

香港VPS服务器如何优化CPU和内存使用率?

# 香港VPS服务器CPU与内存优化全攻略 在香港VPS服务器上优化CPU和内存使用率是提升性能、降低成本的关键。以下是经过验证的优化策略&#xff0c;涵盖从系统配置到应用层调优的全方位方案。 ## 一、系统级优化 ### 1. 内核参数调优 **调整swappiness值**&#xff08;减少交…...

简单-快速-高效——模块化解析controlnet网络结构

资源 ControlNet论文&#xff1a;Adding Conditional Control to Text-to-Image Diffusion Models 官方项目&#xff1a;lllyasviel/ControlNet: Let us control diffusion models ControlNet 1.1项目地址&#xff1a;lllyasviel/ControlNet-v1-1-nightly diffusers框架的Co…...

C语言:字符串处理函数strstr分析

在 C 语言中&#xff0c;strstr 函数用于查找一个字符串中是否存在另一个字符串。它的主要功能是搜索指定的子字符串&#xff0c;并返回该子字符串在目标字符串中第一次出现的位置的指针。如果没有找到子字符串&#xff0c;则返回 NULL。 详细说明&#xff1a; 头文件&#xf…...

跨境企业应对美国加税:策略突围与破局之道

在全球经济一体化的浪潮中&#xff0c;跨境企业的业务发展与国际关系、贸易政策紧密相连。美国作为全球重要的经济体&#xff0c;其加税行为犹如一场突如其来的风暴&#xff0c;给众多跨境企业的运营带来了巨大冲击与挑战。面对这一严峻形势&#xff0c;跨境企业若想在波涛汹涌…...

Rust 是如何层层防错的

一、Rust 的多层防错机制 &#x1f9f1; 第一层&#xff1a;Rust语言自带的“编译时护盾” —— 错误连运行都跑不起来 错误类型Rust 怎么发现的&#xff1f;工具/机制举个例子✅ 语法缺陷写错了代码格式或语法Rust Analyzer&#xff08;智能补全&#xff09;少写了分号、括号…...

一种反激变换器的设计思路(01)

反激式转换器具有低成本且易于构建的优势&#xff0c;常被用作功率较低设备和电器的主要电源。其中固定开关频率&#xff08;FF&#xff09;和可变开关频率&#xff08;QR&#xff09;是两种基本的操作开关模式。本案例中&#xff0c;输入电压&#xff08;Vin&#xff09;为17V…...

Streamlit性能优化:缓存与状态管理实战

目录 &#x1f4cc; 核心特性 &#x1f4cc; 运行原理 &#xff08;1&#xff09;全脚本执行 &#xff08;2&#xff09;差异更新 &#x1f4cc; 缓存机制 ❓为什么使用缓存&#xff1f; 使用st.cache_data的优化方案 缓存适用场景 使用st.session_state的优化方案 &…...

楼宇自控系统凭何成为建筑稳定、高效、安全运行的关键

在现代建筑领域&#xff0c;随着建筑规模的不断扩大和功能的日益复杂&#xff0c;建筑的稳定、高效、安全运行成为了至关重要的课题。楼宇自控系统犹如建筑的“智慧大脑”&#xff0c;凭借其卓越的功能和技术&#xff0c;在这三个关键方面发挥着不可替代的作用&#xff0c;成为…...

【学习自用】配置文件中的配置项

server.port服务器端口&#xff0c;常被用于指定应用程序运行时所监听的端口号spring.datasource.url用于配置数据源的数据库连接URLspring.datasource.username用于指定连接数据库的用户名spring.datasource.password用于配置数据源时设置数据库连接密码的属性mybatis.mapper-…...

《解码 C/C++ 关键字:科技编程的核心指令集》

序号语言关键字原型实现原理功能返回值类型使用示例注意事项应用场景1Cautoauto 数据类型 变量名;函数调用时在栈上分配内存&#xff0c;函数结束自动释放声明自动变量&#xff0c;变量生命周期限于函数执行期间无c<br>void func() {<br> auto int num 10;<br&…...

Linux 性能调优之CPU调优认知

写在前面 博文内容为《性能之巅 系统、企业与云可观测性(第2版)》CPU 章节课后习题答案整理内容涉及: CPU 术语,指标认知CPU 性能问题分析解决CPU 资源负载特征分析应用程序用户态CPU用量分析理解不足小伙伴帮忙指正对每个人而言,真正的职责只有一个:找到自我。然后在心中…...

《P2660 zzc 种田》

题目背景 可能以后 zzc 就去种田了。 题目描述 田地是一个巨大的矩形&#xff0c;然而 zzc 每次只能种一个正方形,而每种一个正方形时 zzc 所花的体力值是正方形的周长&#xff0c;种过的田不可以再种&#xff0c;zzc 很懒还要节约体力去泡妹子&#xff0c;想花最少的体力值…...

Model Context Protocol(MCP)介绍

“Model Context Protocol&#xff08;MCP&#xff09;”是近年来在多模态大模型或可扩展智能系统中出现的一个概念&#xff0c;其主要目标是为大模型提供结构化的上下文管理和动态记忆机制。它解决的是在长时间对话、多轮交互、任务切换等复杂情境中&#xff0c;模型如何理解“…...

解决使用PendingIntent.getBroadcast时出现java.lang.IllegalArgumentException异常的问题

当app为targetSdk31及以上&#xff0c;并且在Android12及以上系统中调用PendingIntent.getBroadcast(context, 0, intent, 0)接口时会抛出异常&#xff1a; java.lang.IllegalArgumentException: com.haier.uhome.uplus.seasia: Targeting S (version 31 and above) requires …...

创建一个简单的HTML游戏站

创建一个简单的HTML游戏站涉及多个步骤&#xff0c;包括规划网站结构、设计用户界面、编写游戏逻辑以及测试和部署。下面是一个详细的步骤指南&#xff1a; 1. 规划网站结构 确定目标受众&#xff1a;了解你的目标用户群体。选择游戏类型&#xff1a;决定你要开发的游戏类型&…...

AIDD-人工智能药物设计-TCMP-12个公开的中药数据库

12个公开的中药数据库 数据库是中药网络药理学研究不可或缺的数据来源之一。目前已经建立了若干中药数据库&#xff0c;提供有关中药的各方面信息&#xff0c;包括疾病、方剂、草药或天然产物、生物活性成分和靶点。这些数据库成为中医药与现代生物医学之间的桥梁&#xff0c;…...

基于大模型的阵发性室上性心动过速风险预测与治疗方案研究

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与目标 1.3 研究方法与数据来源 二、阵发性室上性心动过速概述 2.1 定义与分类 2.2 发病机制与流行病学 2.3 临床表现与诊断方法 三、大模型在阵发性室上性心动过速预测中的应用 3.1 大模型技术原理与特点 3.2 模型构…...

基于金字塔视觉变换的类引导网络高分辨率遥感图像高效语义分割

Class-Guidance Network Based on the Pyramid Vision Transformer for Efficient Semantic Segmentation of High-Resolution Remote Sensing Images 摘要 多分类语义分割中类之间的小差异和类内的大变化是全卷积神经网络的“编码器-解码器”结构没有完全解决的问题&#…...

高级:数据库面试题全攻略

一、引言 数据库是软件开发中不可或缺的组件&#xff0c;面试官通过相关问题&#xff0c;考察候选人对数据库核心概念的理解、实际应用能力以及在复杂场景下的问题解决能力。本文将深入解读数据库的索引、事务、锁机制等常见面试问题&#xff0c;结合实际开发场景&#xff0c;…...

如何避免Python爬虫重复抓取相同页面?

在网络爬虫开发过程中&#xff0c;重复抓取相同页面是一个常见但必须解决的问题。重复抓取不仅会浪费网络带宽和计算资源&#xff0c;降低爬虫效率&#xff0c;还可能导致目标网站服务器过载&#xff0c;甚至触发反爬机制。本文将深入探讨Python爬虫中避免重复抓取的多种技术方…...

LeetCode.02.04.分割链表

分割链表 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x …...

鸿蒙开发_ARKTS快速入门_语法说明_渲染控制---纯血鸿蒙HarmonyOS5.0工作笔记012

然后我们再来看渲染控制 首先看条件渲染,其实就是根据不同的状态,渲染不同的UI界面 比如下面这个暂停 开启播放的 可以看到就是通过if 这种条件语句 修改状态变量的值 然后我们再来看这个, 下面点击哪个,上面横线就让让他显示哪个 去看一下代码 可以看到,有两个状态变量opt…...

MOP数据库中的EXPLAIN用法

EXPLAIN 是 SQL 中的一个非常有用的工具&#xff0c;主要用于分析查询语句的执行计划。执行计划能展示数据库在执行查询时的具体操作步骤&#xff0c;像表的读取顺序、使用的索引情况、数据的访问方式等&#xff0c;这有助于我们对查询性能进行优化。 语法 不同的数据库系统&…...

软考 系统架构设计师系列知识点 —— 设计模式之抽象工厂模式

本文内容参考&#xff1a; 软考 系统架构设计师系列知识点之设计模式&#xff08;2&#xff09;_系统架构设计师中考设计模式吗-CSDN博客 https://baike.baidu.com/item/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/2361182 特此致谢&#xff01; Abstract Fac…...

告别水下模糊!SU-YOLO:轻量化+尖峰神经网络,用“类脑计算”实现水下目标毫秒级识别

目录 一、摘要 二、引言 三、相关工作 SNN 物体检测 水下物体探测 水下图像去噪 归一化 四、方法 水下尖峰YOLO 尖峰干扰器 SU-Block SpikeSPP 编码器和检测头 分批归一化 五、Coovally AI模型训练与应用平台 六、实验结果 数据集和实施细节 数据集 实施细节…...

Three.js 系列专题 8:实战项目 - 构建一个小型 3D 游戏

内容概述 本专题将通过一个实战项目展示 Three.js 的综合应用。游戏包含迷宫生成、角色移动、相机控制和简单的物理碰撞检测(可选)。这将帮助你将之前学到的知识融会贯通。 学习目标 整合几何体、光照、动画和交互知识。实现基本的游戏逻辑和用户控制。可选:使用 Cannon.j…...

嵌入式笔试(一)

C语言和嵌入式软件 面试题(共10题 时间30分钟) 1. 请写出下面声明的含义。 int(*s[10])(int);定义了一个数组为s包含十个元素,每个元素都是函数指针,函数的参数为一个int类型,返回值也是int类型2. 选择题 设有一台计算机,它有一条加法指令,每次可计算三个数的和。如果要…...

spark 的流量统计案例

创建一个目录为data...

局域网访问 Redis 方法

局域网访问 Redis 方法 默认情况下&#xff0c;Redis 只允许本机 (127.0.0.1) 访问。如果你想让局域网中的其他设备访问 Redis&#xff0c;需要 修改 Redis 配置&#xff0c;并确保 防火墙放行端口。 方法 1&#xff1a;修改 Redis 配置 1. 修改 redis.conf&#xff08;或 me…...

LeetCode题五:合并两个有序链表

基本思路其实就是&#xff1a;先建立一个空链表&#xff0c;然后将尾节点放在头结点上&#xff1b; 如果第一个链表节点值较小&#xff0c;那么先将list1插入新链表中&#xff0c;然后将尾节点后移&#xff1b;相同的&#xff0c;第二个也需要比较&#xff1b;移动新链表的指针…...

深入探索 `malloc`:内存分配失败的原因及正确使用规范

文章目录 一、malloc 内存分配失败的常见原因1. 内存不足2. 内存越界访问3. 内存碎片化4. 系统限制5. 错误的使用方式 二、如何正确使用 malloc1. 检查返回值2. 释放内存3. 避免内存越界4. 优化内存使用5. 调整系统参数6. 使用高效的内存分配器 三、总结 在 C 语言中&#xff0…...

处理Excel的python库openpyxl、xlrd、xlwt、panda区别

openpyxl、xlrd、xlwt、pandas 都能处理 Excel 表格&#xff0c;但用途和适合的场景不同。今天做个总结&#xff1a; 库名功能支持格式读写支持样式备注openpyxl全面的.xlsx处理库.xlsx&#xff08;Excel2007&#xff09;✅✅✅首选xlrd读取.xls文件的老牌工具.xls&#xff08…...

【C++11】特殊类的设计 单例模式 类型转换

目录 一、特殊类的设计&#xff1a; 1、设计一个不能够拷贝的类&#xff1a; 2、设计一个只能在堆上创建的类 3、设计一个只能在栈上创建的类 4、设计一个不能被继承的类&#xff1a; 二、单例模式&#xff1a; 设计一个只能创建一个对象的类&#xff1a; 饿汉模式&…...

基于vue框架的助农特色农产品销售系统i7957(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能:用户,商品分类,农产品信息,特价商品,爱心捐赠 开题报告内容 基于Vue框架的助农特色农产品销售系统开题报告 一、研究背景与意义 &#xff08;一&#xff09;研究背景 随着乡村振兴战略的深入实施&#xff0c;特色农产品作为农村经济的重要组成部…...

Linux 学习笔记(3):ls 命令深入剖析与实践应用(期末、期中复习必备)

前言 一、ls 命令基础语法 命令示例 二、工作目录与 HOME 目录 1.工作目录 2.HOME 目录 三、结语 前言 在 Linux 系统的学习旅程中&#xff0c;基础命令的掌握是迈向熟练操作的关键一步。其中&#xff0c;ls 命令作为我们探索系统文件和目录结构的常用工具&#xff0c;有着…...

最简CNN based RNN源码

1.源码&#xff1a; GitCode - 全球开发者的开源社区,开源代码托管平台 最终的效果&#xff1a; 数据集是20个周期&#xff0c;1024点sin(x)加了偏置。其中用于训练的有1024-300点。最后300点用来进行测试。上面的右侧输出的&#xff0c;其实对应左侧x73之后的波形&#xff0…...