【问题分析】锁屏界面调起google语音助手后壁纸不可见【Android 14】
1 问题描述
为系统和锁屏分别设置两张不同的壁纸,然后在锁屏界面长按Power调起google语音助手后,有时候会出现壁纸不可见的情况,如以下截图所示:
有的时候又是正常的,但显示的也是系统壁纸,并非是锁屏壁纸。
后面我本地多次尝试,发现了一些规律:
1)、同时设置系统和锁屏壁纸为壁纸A,此时不会有问题。
2)、在第1步的基础上,单独将锁屏壁纸设置为壁纸B,此时也不会有问题。
3)、在第2步的基础上,单独将系统壁纸设置为壁纸C,出现问题。
添加了log后,大概知道问题出现的原因了,不过这里先分析一下WallpaperController中关于计算壁纸可见性的一些代码逻辑吧,之前零零散散看过一点,希望这次能够趁分析这个问题的机会,做一些总结。
2 WallpaperController代码分析
2.1 WallpaperController.adjustWallpaperWindows
更新壁纸的起点在WallpaperController.adjustWallpaperWindows:
1)、WallpaperController.findWallpaperTarget用来寻找壁纸的目标窗口,将寻找的结果放到成员变量WallpaperController.mFindResults中。
2)、WallpaperController.updateWallpaperWindowsTarget根据成员变量WallpaperController.mFindResults更新成员变量WallpaperController.mWallpaperTarget。
3)、最后如果WallpaperController.mWallpaperTarget不为空,那么认为壁纸可见,再调用WallpaperController.updateWallpaperTokens更新壁纸的可见性。
这里有两个成员变量mFindResults和mWallpaperTarget要先介绍一下。
首先是mWallpaperTarget,定义为:
白话点说就是壁纸的目标窗口,比如一个Activity的窗口在显示的时候被设置为支持壁纸显示,比如Launcher的窗口,那么这个窗口就可以作为壁纸的目标窗口。如果我们遍历所有的窗口后,找不到一个窗口可以作为壁纸的目标窗口,那么就说明所有的窗口都不支持壁纸显示,那壁纸也就会被设置为不可见。如果可以找到一个壁纸的目标窗口,那么这个目标窗口就会被保存到成员变量WallpaperController.mWallpaperTarget中。
接着是成员变量mFindResults,定义为:
它是一个FindWallpaperTargetResult类型的成员变量,这里则需要知道FindWallpaperTargetResult这个类的作用,它定义在WallpaperController里:
从类的注释上以及类名来看,这个类是用来保存寻找壁纸目标窗口操作的结果。
再看它的成员变量,首先是TopWallpaper类型的mTopWallpaper,它又是定义在FindWallpaperTargetResult中的内部类,只有两个成员变量,mTopHideWhenLockedWallpaper和mTopShowWhenLockedWallpaper,结合这里的注释以及我看了代码后的理解:
mTopHideWhenLockedWallpaper和mTopShowWhenLockedWallpaper都可以设置为壁纸窗口,即“Window{d837259 u0 com.android.systemui.wallpapers.ImageWallpaper}”,并且同一时间它们两个中间只能有一个被设置:
1)、如果mTopHideWhenLockedWallpaper被设置(即不为空),说明此时壁纸只能在Home界面可见,锁屏界面不可见。
2)、如果mTopShowWhenLockedWallpaper被设置(即不为空),说明此时壁纸在Home界面以及锁屏界面均可见。
后面分析到相关代码的时候就能了解上面的意义了。
然后再解释几个后续会分析到的成员变量:
1)、mNeedsShowWhenLockedWallpaper,如果在一个Activity界面可以在锁屏界面上显示,比如通话界面,如果这个Activity或者窗口不是全屏的,那么就会把mNeedsShowWhenLockedWallpaper的值设置为true。在这种场景下,即使我们没有为锁屏壁纸找到一个目标窗口,那么我们可能也是需要将锁屏壁纸显示出来的。
2)、useTopWallpaperAsTarget,结合上面第一点来说,如果后续经过我们遍历所有窗口后,我们找不到任何一个窗口可以作为壁纸的目标窗口,但是在一些特殊场景下,我们又是需要将壁纸显示出来的,那么我们就将这个值设置为true,表示我们将TopWallpaper中的mTopHideWhenLockedWallpaper或者mTopShowWhenLockedWallpaper保存的壁纸WindowState本身作为壁纸的目标窗口,至于从这两者中的哪个里面取,则是看当前是否处于锁屏。
3)、wallpaperTarget,这个没什么好说的,在寻找壁纸的目标窗口阶段,我们将寻找的结果保存在FindWallpaperTargetResult.wallpaperTarget中,后续在WallpaperController.updateWallpaperWindowsTarget中,我们就从FindWallpaperTargetResult.wallpaperTarget中拿寻找的结果。
接下来看寻找壁纸的目标窗口的代码,WallpaperController.findWallpaperTarget。
2.2 WallpaperController.findWallpaperTarget
这个方法用来寻找壁纸的目标窗口,是我们本篇文章的分析重点。
2.2.1 FindWallpaperTargetResult.reset
调用FindWallpaperTargetResult.reset重置FindWallpaperTargetResult的保存的所有信息:
2.2.2 Freeform的情况
如果当前有WINDOWING_MODE_FREEFORM类型的App显示:
那么就设置FindWallpaperTargetResult.useTopWallpaperAsTarget为true:
即在Freeform的场景下直接将壁纸进行显示,不需要再额外找一个目标窗口了,这算是一种对需要显示壁纸的特殊场景的处理。
2.2.3 WallpaperController.mFindWallpapers
接着对所有的窗口进行第一次遍历:
如果这个窗口是壁纸类型的,那么继续判断,如果WallpaperWindowToken.canShowWhenLocked返回true,说明此时壁纸是允许在锁屏界面显示的,那么就将这个壁纸窗口保存在FindWallpaperTargetResult.mTopShowWhenLockedWallpaper中,后续如果我们检测到FindWallpaperTargetResult.mTopShowWhenLockedWallpaper不为空,那么就说明当前壁纸是允许在锁屏界面显示的。否则就将这个壁纸窗口保存在FindWallpaperTargetResult.mTopHideWhenLockedWallpaper中,后续如果我们检测到FindWallpaperTargetResult.mTopHideWhenLockedWallpaper不为空,那么就说明当前壁纸是只能在Home界面显示的。
另外根据我本地的测试,当同时设置系统壁纸和锁屏壁纸时,WallpaperWindowToken.setShowWhenLocked这个方法会被调用,设置WallpaperWindowToken.mShowWhenLocked为true,调用堆栈为:
2.2.4 WallpaperController.mFindWallpaperTargetFunction
对所有的窗口进行第二次遍历:
这里的逻辑也比较复杂,省略不太重要的部分,首先看一种特殊的情况:
如果在锁屏状态,并且此时正在遍历的这个窗口盖在锁屏界面,那么继续判断:
1)、如果现在锁屏的状态为“occluded”。
或者
2)、当前该在锁屏界面上的那个窗口处于Transition,那一般就是open或者close。
该窗口或者该窗口对应的ActivityRecord是否是全屏的,如果不是,那么将mNeedsShowWhenLockedWallpaper设置为true。很好理解,如果是一个非全屏的窗口盖在锁屏界面上,如果不显示锁屏壁纸,那么屏幕上没有被这个非全屏窗口覆盖的部分就会由于没有内容显示从而黑屏。
这里稍微提一下这个对窗口是否处于Transitiond的判断,如果只是判断锁屏的状态为“occluded”,那么可能会出现锁屏状态切换为“occluded”不够及时,从而出现短暂黑屏的现象,就比如我这里长按Power键唤起google语音助手的情况:
所以我们需要加上对窗口是否处于Transition的判断,确保壁纸在Transition早期阶段就显示。
判断过这种特殊场景后,接着对这个正在遍历的窗口进行判断,如果这个窗口在屏幕上,并且已经绘制完成了,那么调用WindowState.hasWallpaper方法去判断该窗口是否支持显示壁纸(这里就不分析动画过程中显示壁纸的情况了):
这是更一般的情况。
涉及LetterBox的情况比较少见,最常见的还是通过检查窗口是否配置了FLAG_SHOW_WALLPAPER这个窗口标志位来判断这个窗口是否支持显示壁纸,就比如Launcher。
2.2.5 FindWallpaperTargetResult.setUseTopWallpaperAsTarget
回到WallpaperController.findWallpaperTarget方法:
这里承接第4步,如果在第4步我们发现一个非全屏的窗口盖在了锁屏界面上,那么就会将FindWallpaperTargetResult.mNeedsShowWhenLockedWallpaper设置为true。
接着在这里,就调用FindWallpaperTargetResult.setUseTopWallpaperAsTarget设置FindWallpaperTargetResult.useTopWallpaperAsTarget为true:
来保证后续壁纸可以显示,这个场景和Freeform出现的场景处理方式一致,即对需要显示壁纸的特殊场景的一种处理。
2.2.6 FindWallpaperTargetResult.setWallpaperTarget
来看最后的一点内容:
如果FindWallpaperTargetResult.wallpaperTarget为空,说明通过两次遍历我们没有找到壁纸的目标窗口,但是FindWallpaperTargetResult.useTopWallpaperAsTarget为true,又说明我们的确想显示壁纸,那么就调用FindWallpaperTargetResult.getTopWallpaper看看能不能返回一个壁纸窗口,如果可以,那么就调用FindWallpaperTargetResult.setWallpaperTarget将壁纸的目标窗口设置为壁纸本身。但是也可能会返回null,看下FindWallpaperTargetResult.getTopWallpaper的内容:
前面说过了,如果将壁纸窗口保存在mTopHideWhenLockedWallpaper中,说明当前壁纸只能在Home界面显示,不能在锁屏界面显示。如果将壁纸窗口保存在mTopShowWhenLockedWallpaper中,说明当前壁纸可以在Home界面以及锁屏界面显示。这里的代码大概就是这种逻辑,比较简单,不再赘述。
需要注意的是这里的返回值可能为空,我们分析的这个问题就是因为这里返回空所以出现了壁纸不可见的情况导致了黑屏,我们后续分析问题产生的原因。
2.3 WallpaperController.updateWallpaperWindowsTarget
WallpaperController.updateWallpaperWindowsTarget这个方法,我看了下好像没有太多可以说的,就是把上一步寻找壁纸的目标窗口的结果保存到WallpaperController的成员变量mWallpaperTarget中。
2.4 WallpaperController.updateWallpaperTokens
回到WallpaperController.adjustWallpaperWindows中,如果WallpaperController.mWallpaperTarget不为空,那么调用WallpaperController.updateWallpaperTokens设置壁纸的可见性:
这里需要注意的一点就是,及时这里的传参visibility是true,后续可能也无法将壁纸变为可见,因为这里还有额外的判断。
首先这里的成员变量mWallpaperTokens定义为:
是一个WallpaperWindowToken的队列,在WallpaperWindowToken创建的时候,会把它加入到mWallpaperTokens中。
接着这里会调用FindWallpaperTargetResult.getTopWallpaper来获取当前的壁纸窗口,只有这个壁纸窗口不为空,并且在mWallpaperTokens中,我们才能将壁纸的可见性设置为true。
后续的WallpaperWindowToken.updateWallpaperWindows就不分析了。
3 问题分析
代码分析完了,现在分析问题。
根据我之前本地操作的结果:
1)、同时设置系统和锁屏壁纸为壁纸A,此时不会有问题。
2)、在第1步的基础上,单独将锁屏壁纸设置为壁纸B,此时也不会有问题。
3)、在第2步的基础上,单独将系统壁纸设置为壁纸C,出现问题。
3.1 同时设置系统和锁屏壁纸为壁纸A
这个路径下,会WallpaperWindowToken.setShowWhenLocked这个方法会被调用,设置WallpaperWindowToken.mShowWhenLocked为true,调用堆栈为:
对所有窗口进行mFindWallpapers遍历时,由于WallpaperWindowToken.mShowWhenLocked为true,因此会设置mTopShowWhenLockedWallpaper为壁纸窗口。
对所有窗口进行mFindWallpaperTargetFunction遍历时,由于google语音助手这个显示在锁屏界面之上的界面对应的ActivityRecord是非全屏的,因此会设置FindWallpaperTargetResult.mNeedsShowWhenLockedWallpaper为true:
并且由于所有窗口都不满足作为壁纸的目标窗口的条件,因此这一步没有找到目标窗口。
后续再回到WallpaperController.findWallpaperTarget:
现在FindWallpaperTargetResult.mNeedsShowWhenLockedWallpaper为true,所以这里会调用FindWallpaperTargetResult.setUseTopWallpaperAsTarget来将FindWallpaperTargetResult.useTopWallpaperAsTarget设置为true,那么接着就会调用FindWallpaperTargetResult.getTopWallpaper尝试获取壁纸窗口,并且将返回的结果作为目标窗口:
这里由于我们处于锁屏,因此会返回TopWallpaper.mTopShowWhenLockedWallpaper,并且根据我们的分析,因为WallpaperWindowToken.mShowWhenLocked为true,因此之前我们的确是将壁纸窗口保存在了TopWallpaper.mTopShowWhenLockedWallpaper中的,因此这里就可以返回壁纸窗口,并且将其设置为壁纸的目标窗口。
这种情况最终是会找到一个壁纸的目标窗口的,因此壁纸是可见的。
3.2 在第1步的基础上,单独将锁屏壁纸设置为壁纸B
这种情况下,和3.1节的分析内容不会有区别,所以也不会有什么问题。
唯一有点奇怪的是,此时显示的是系统壁纸,而非锁屏壁纸。也不能说奇怪,毕竟系统壁纸才是真正的壁纸,是有一个专门的壁纸窗口对应,而锁屏壁纸,应该只是锁屏界面为自己设置的一张背景图。
3.3 在第2步的基础上,单独将系统壁纸设置为壁纸C
这种情况下,就会出现问题,原因出在哪儿呢?
看了下log,发现此时WallpaperWindowToken.mShowWhenLocked变成了false,那么对所有窗口进行mFindWallpapers遍历时,由于WallpaperWindowToken.mShowWhenLocked为false,因此会设置TopWallpaper.mTopHideWhenLockedWallpaper为壁纸窗口。
而在后续调用FindWallpaperTargetResult.getTopWallpaper尝试获取壁纸窗口时,由于此时处于锁屏,因此返回的仍然是TopWallpaper.mTopShowWhenLockedWallpaper。这就是问题的原因所在了,我们将壁纸窗口保存在了TopWallpaper.mTopHideWhenLockedWallpaper中,那么TopWallpaper.mTopShowWhenLockedWallpaper就是空的,因此调用FindWallpaperTargetResult.getTopWallpaper返回的就是空的,最终结果就是没有为壁纸找到一个目标窗口,壁纸在锁屏状态下变为不可见。
那么为什么WallpaperWindowToken.mShowWhenLocked变成了false呢,我也没看到WallpaperWindowToken.setShowWhenLocked方法有调用将WallpaperWindowToken.mShowWhenLocked设置为false啊?原来是设置系统壁纸的时候,直接重新创建了一个新的WallpaperWindowToken对象:
WallpaperWindowToken.mShowWhenLocked默认是false,并且后续没有再调用WallpaperWindowToken.setShowWhenLocked将WallpaperWindowToken.mShowWhenLocked设置为true,所以就出现了问题。
最后再看下同时设置系统壁纸和锁屏壁纸的情况吧,同时设置了壁纸后,会重新创建一个WallpaperWindowToken对象,接着就是调用WallpaperWindowToken.setShowWhenLocked设置WallpaperWindowToken.mShowWhenLocked:
看调用堆栈,都在WallpaperManagerService$DisplayConnector.connectLocked方法中:
看到这里需要更正上面的一个说法,就是单独设置了系统壁纸的时候,其实也是调用了WallpaperWindowToken.setShowWhenLocked了,但是设置的是false,因为只是针对系统壁纸生效,而本来WallpaperWindowToken.mShowWhenLocked默认的就是false,所以我之前添加的log没有打印…
用白话总结一下这个问题,给我个人的感觉就是:
1)、setShowWhenLocked这个属性表示的壁纸自己支持不支持在锁屏界面显示,是壁纸自己决定的,或者说是Launcher在设置壁纸的时候决定的。
2)、WallpaperController用来决策壁纸是否需要在锁屏界面上显示。
这个问题很明显就是这两者冲突了,WallpaperController的逻辑觉得这个时候壁纸应该在锁屏界面显示,但是还是需要看看在Launcher设置壁纸的时候,设定壁纸是否可以在锁屏界面显示。如果壁纸不支持在锁屏界面显示,那么WallpaperController也不能强行让壁纸在锁屏界面上显示。
4 解决方案
分析到这里感觉这应该是google的原生问题,但是pixel却没有问题,不过发现了一个区别,就是将系统壁纸和锁屏壁纸分别设置为不同的壁纸图片后,在锁屏界面长按Power唤起语音助手时,发现pixel显示的是壁纸是锁屏壁纸,而我们的机器要么显示的是系统壁纸,要么就不显示。
dump信息看了下,原来pixel的机器有两个WallpaperWindowToken,分别管理系统壁纸和锁屏壁纸:
而我们的机器只有一个,是系统壁纸:
锁屏壁纸只是NotificationShade为自己设置的一张背景。
跟SystemUI的同事沟通了一下,得知pixel用的似乎不是aosp里的SystemUI,而是自己另外一套的SystemUI,并且将aosp的SystemUI推到手机里也有问题,那这个问题无法参考pixel进行修改了。
回顾一下问题发生的原因,即WallpaperController判断出锁屏界面需要显示壁纸,壁纸却又说我的出厂设定就是只能在Home界面显示,我就不显示,WallpaperController拗不过壁纸,所以出现了黑屏。
如果要解决这个黑屏问题,我目前能想到的就是围绕FindWallpaperTargetResult.mNeedsShowWhenLockedWallpaper这个变量做文章, 既然这个变量被设置为true了,就说明当下的确需要壁纸去显示了,不管壁纸它支持不支持在锁屏界面上显示,它都得直楞起来,先给我显示了再说。
相关文章:

【问题分析】锁屏界面调起google语音助手后壁纸不可见【Android 14】
1 问题描述 为系统和锁屏分别设置两张不同的壁纸,然后在锁屏界面长按Power调起google语音助手后,有时候会出现壁纸不可见的情况,如以下截图所示: 有的时候又是正常的,但显示的也是系统壁纸,并非是锁屏壁纸…...

Java入门基础学习笔记8——注释
1、注释: 注释是写在程序中对代码进行解释说明的文件,方便自己和其他人查看,以便理解程序的。 package cn.ensource.note;/**文档注释文档注释 */ public class NoteDemo {public static void main(String[] args) {// 单行注释System.out.…...

上班工资太低了,哪些副业可以多赚钱?
今天给各位分享最赚钱的副业方式的知识,其中也会对比较赚钱的副业进行解释. 1、网站接单 一般20页左右的PPT报价基本在200-400元。如果能每周接单,一个月就有接近1000元的副业收入。提交摄影和绘画作品 比起画画,靠摄影赚点外快更容易一点。…...

原子学习笔记4——GPIO 应用编程
一、应用层如何操控 GPIO 与 LED 设备一样,GPIO 同样也是通过 sysfs 方式进行操控,进入到/sys/class/gpio 目录下,如下所示: gpiochipX:当前 SoC 所包含的 GPIO 控制器,我们知道 I.MX6UL/I.MX6ULL 一共包…...
查看iqn编码
cat /etc/iscsi/initiatorname.iscsi ## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames. InitiatorNameiqn.2004-10.com.ubuntu:01:9ebe1a68...

如何安全的使用密码登录账号(在不知道密码的情况下)
首先,需要用到的这个工具: 度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 1、打开工具,进入账号密码模块,如图 2、看到鼠标移动到密码那一栏有提示,按住Ctrl或者Alt点击或者双击就能复制内容&…...
软件需求和设计评审
目录 引言 1. 软件评审的方法和技术 2. 产品需求评审:构建正确的产品 3. 设计评审:构建正确的产品 4. 软件评审的最佳实践 结语 引言 在软件开发的迷宫中,需求和设计评审是通往成功产品的关键门户。它们是确保软件质量和满足用户需求的…...

论文笔记ColdDTA:利用数据增强和基于注意力的特征融合进行药物靶标结合亲和力预测
ColdDTA发表在Computers in Biology and Medicine 的一篇一区文章 突出 • 数据增强和基于注意力的特征融合用于药物靶点结合亲和力预测。 • 与其他方法相比,它在 Davis、KIBA 和 BindingDB 数据集上显示出竞争性能。 • 可视化模型权重可以获得可解释的见解。 …...

如何防止WordPress网站内容被抓取
最近在检查网站服务器的访问日志的时候,发现了大量来自同一个IP地址的的请求,用站长工具分析确认了我的网站内容确实是被他人的网站抓取了,我第一时间联系了对方网站的服务器提供商投诉了该网站,要求对方停止侵权行为,…...
全球化战略中的技术支柱:出海企业的网络技术解决方案
随着全球市场的一体化,中国的电商与游戏行业越来越倾向于扩展国际市场,这一过程被称为“出海”。成功的出海战略不仅需要强大的市场洞察和文化适应能力,还需依赖高效的网络技术,包括SOCKS5代理、代理IP、以及全面的网络安全策略。…...

在Linux上安装并运行RabbitMQ
目录 准备CentOS服务器 下载rabbit-server和erlang文件 启动RabbitMQ服务 准备CentOS服务器 两个命令,选一个能用的,查看CentOS服务器的版本 lsb_release -a下载rabbit-server和erlang文件 参考文章:http://t.csdnimg.cn/t8BbM 1、创建新…...

使用 docker-compose 搭建个人博客 Halo
说明 我这里使用的是 Halo 作为博客的工具,毕竟是开源了,也是使用 Java 写的嘛,另外一点就是使用 docker 来安装(自动挡,不用自己考虑太多的环境因素),这样子搭建起来更快一点,我们…...

《这就是ChatGPT》读书笔记
书名:这就是ChatGPT 作者:[美] 斯蒂芬沃尔弗拉姆(Stephen Wolfram) ChatGPT在做什么? ChatGPT可以生成类似于人类书写的文本,它基本任务是弄清楚如何针对它得到的任何文本产生“合理的延续”。当ChatGPT写…...

更专业的汽车软件研发工具链,怿星重磅发布新产品
怿星科技在2024北京国际车展同期举办主题为“创新引领未来——聚焦智能汽车软件新基建”的新产品发布会,重磅推出1款绝对优势产品和4套场景解决方案。同时举行了4场热点技术研讨:国产工具链的机遇与挑战、新架构下的的车载DDS应用探索及测试方案介绍、软…...

Stable Diffusion:AI绘画的新纪元
摘要: Stable Diffusion(SD)作为AI绘画领域的新星,以其开源免费、强大的生成能力和高度的自定义性,正在引领一场艺术与技术的革命。本文旨在为读者提供Stable Diffusion的全面介绍,包括其原理、核心组件、安…...
有5个excel表,每个表有6列。用python把这5个表合成1个表。
要将五个Excel表格合并成一个表格,我们可以使用pandas库,它提供了一个简单且强大的方式来处理和分析数据。下面是一个步骤说明和示例代码: 步骤: 安装pandas和openpyxl(如果你还没有安装的话):…...

【回溯算法】【Python实现】最大团问题
文章目录 [toc]问题描述回溯算法Python实现时间复杂性 问题描述 给定无向图 G ( V , E ) G (V , E) G(V,E),如果 U ⊆ V U \subseteq V U⊆V,且对任意 u u u, v ∈ U v \in U v∈U有 ( u , v ) ∈ E (u , v) \in E (u,v)∈E,则称…...

CMakeLists.txt语法规则:foreach 循环基本用法
一. 简介 cmake 中除了 if 条件判断之外,还支持循环语句,包括 foreach()循环、while()循环。 本文学习 CMakeLists.txt语法中的循环语句。 CMakeLists.txt语法中 有两种 循环实现方式:foreach循环与 while循环。 二. CMakeLists.txt语法规则…...

redis集群-主从机连接过程
首先从机需要发送自身携带的replid和offset向主机请求连接 replid:replid是所有主机在启动时会生成的一个固定标识,它表示当前复制流的id,当从机第一次请求连接时,主机会将自己的replid发送给从机,从机在接下来的请求…...

去哪里找高清视频素材?推荐几个短视频素材免费网站
在数字时代,视频内容的质量直接影响观众的吸引力和留存率。尤其是高清、4K视频素材和可商用素材,它们在提升视觉质量和叙事深度方面起到了至关重要的作用。以下是一些国内外的顶级视频素材网站,它们提供的资源将为您的创作提供极大的支持和灵…...
零基础认知企业级数据分析平台如何落实数据建模(GAI)
理解数据建模的基本概念 数据建模是将业务需求转化为数据结构和关系的过程,核心目标是构建可支撑分析、预测或决策的数据模型。零基础需从以下维度入手: 业务理解:明确业务问题(如销售预测、用户分群),与…...

第五十九节:性能优化-GPU加速 (CUDA 模块)
在计算机视觉领域,实时性往往是关键瓶颈。当传统CPU处理高分辨率视频流或复杂算法时,力不从心。本文将深入探索OpenCV的CUDA模块,揭示如何通过GPU并行计算实现数量级的性能飞跃。 一、GPU加速:计算机视觉的必由之路 CPU的强项在于复杂逻辑和低延迟任务,但面对图像处理中高…...
(面试)OkHttp实现原理
OkHttp 是一个高效的 HTTP 客户端,被广泛应用于 Android 和 Java 应用中。它提供了许多强大的特性,例如连接池、透明的 GZIP 压缩、HTTP/2 支持等。理解 OkHttp 的实现原理有助于更好地使用和调试它。 以下是 OkHttp 的一些核心实现原理: 1…...

FastAPI安全认证:从密码到令牌的魔法之旅
title: FastAPI安全认证:从密码到令牌的魔法之旅 date: 2025/06/02 13:24:43 updated: 2025/06/02 13:24:43 author: cmdragon excerpt: 在FastAPI中实现OAuth2密码流程的认证机制。通过创建令牌端点,用户可以使用用户名和密码获取JWT访问令牌。代码示例展示了如何使用Cry…...

【irregular swap】An Examination of Fairness of AI Models for Deepfake Detection
文章目录 An Examination of Fairness of AI Models for Deepfake Detection背景points贡献深伪检测深伪检测审计评估检测器主要发现评估方法审计结果训练分布和方法偏差An Examination of Fairness of AI Models for Deepfake Detection 会议/期刊:IJCAI 2021 作者: 背景…...
React 播客专栏 Vol.18|React 第二阶段复习 · 样式与 Hooks 全面整合
视频版 🎙 欢迎回到《前端达人 React播客书单》第 18 期。 今天,我们将对第二阶段的内容进行系统复盘,重点是两个关键词:样式 与 Hooks。 样式,决定组件“长什么样”Hooks,决定组件“怎么动起来” 我们不但…...

【笔记】Windows 部署 Suna 开源项目完整流程记录
#工作记录 因篇幅有限,所有涉及处理步骤的详细处理办法请参考文末资料。 Microsoft Windows [Version 10.0.27868.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗…...
排序算法-归并排序与快速排序
归并排序与快速排序 快速排序是利用的递归思想:选取一个基准数,把小于基准数的放左边 大于的放右边直到整个序列有序 。快排分割函数 O(lognn), 空间 :没有额外开辟新的数组但是递归树调用函数会占用栈内存 O(logn) 。 归并排序:在递归返回的…...

深入理解 SELinux:通过 Nginx 和 SSH 服务配置实践安全上下文与端口策略
目录 一、引言 二、实验环境说明 三、实验 1:Nginx 服务安全上下文配置 3.1 实验目标 3.2 操作步骤 1. 开启 SELinux 并重启系统 2. 安装 Nginx 并创建自定义目录 3. 配置 Nginx 指向自定义目录 4. 分析 SELinux 上下文冲突 5. 修改上下文为合法类型 6. 验…...
WPF 全局加载界面、多界面实现渐变过渡效果
WPF 全局加载界面与渐变过渡效果 完整实现方案 MainWindow.xaml <Window x:Class"LoadingScreenDemo.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml&quo…...