【问题分析】锁屏界面调起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了,就说明当下的确需要壁纸去显示了,不管壁纸它支持不支持在锁屏界面上显示,它都得直楞起来,先给我显示了再说。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/324380.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Map按value降序并统计

package com.ldj.cloud.user.demo;import java.util.*;/*** User: ldj* Date: 2024/5/11* Time: 10:03* Description: map按value降序*/ public class Tr {public static void main(String[] args) {ArrayList<String> list new ArrayList<>();list.add("a&q…

纯血鸿蒙APP实战开发——阅读翻页方式案例

介绍 本示例展示手机阅读时左右翻页&#xff0c;上下翻页&#xff0c;覆盖翻页的功能。 效果图预览 使用说明 进入模块即是左右翻页模式。点击屏幕中间区域弹出上下菜单。点击设置按钮&#xff0c;弹出翻页方式切换按钮&#xff0c;点击可切换翻页方式。左右翻页方式可点击翻…

【前端】JavaScript的WebAPI | DOM | 获取元素 | 事件 | 操作元素 | 操作节点

文章目录 [toc] JavaScript的WebAPI一、DOM1.DOM树2.获取元素1.querySelector2.querySelectorAll 3.事件事件三要素点击事件键盘事件 4.操作元素获取/修改元素内容获取/修改元素属性获取/修改表单属性获取/修改样式属性行内样式操作类名样式操作 5.操作节点新增节点删除节点 Ja…

EasyRecovery数据恢复软件2024最新免费无需激活版下载

EasyRecovery数据恢复软件是一款功能强大、操作简便的数据恢复工具&#xff0c;旨在帮助用户解决各种数据丢失问题。无论是由于误删除、格式化、磁盘损坏还是其他原因导致的数据丢失&#xff0c;EasyRecovery都能提供有效的恢复方案。以下是对EasyRecovery软件功能的详细介绍。…

XWiki 服务没有正确部署在tomcat中,如何尝试手动重新部署?

1. 停止 Tomcat 服务 首先&#xff0c;您需要停止正在运行的 Tomcat 服务器&#xff0c;以确保在操作文件时不会发生冲突或数据损坏&#xff1a; sudo systemctl stop tomcat2. 清空 webapps 下的 xwiki 目录和 work 目录中相关的缓存 删除 webapps 下的 xwiki 目录和 work …

IP报文在设备间传递的封装过程

IP报文传递过程 1、PC1访问PC2报文传递过程1.1、PC1准备数据请求报文封装1.2、PC1准备ARP请求报文1.3、PC2准备ARP响应报文1.4、PC1完成数据请求报文封装 2、PC1访问PC3报文传递过程2.1、PC1准备数据请求报文封装2.2、PC1准备获取网关MAC地址的ARP请求报文2.3、网关准备ARP响应…

Github2024-05-10开日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-05-10统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4TypeScript项目4JavaScript项目1Lua项目1C项目1Rust项目1Dart项目1 RustDesk: 用Rust编写的开源远…

【Linux】进程间通信之共享内存

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误的话&#xff0c;还望指出&…

【Linux系统编程】第十六弹---冯诺依曼体系结构与操作系统

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、冯诺依曼体系结构 2、操作系统原理 2.1、什么是操作系统&#xff1f; 2.2、用图解释操作系统 2.3、理解操作系统 总结 …

QT的TcpServer

Server服务器端 QT版本5.6.1 界面设计 工程文件&#xff1a; 添加 network 模块 头文件引入TcpServer类和TcpSocket&#xff1a;QTcpServer和QTcpSocket #include <QTcpServer> #include <QTcpSocket>创建server对象并实例化&#xff1a; /*h文件中*/QTcpServer…

NAND Flash 与 NOR Flash间的区别

非易失性存储器是一种即使未通电也能保持其内容的存储器。非易失性存储器可以有不同的形式: ROM – 只读存储器&#xff0c;数据写入一次&#xff0c;允许多次读取访问。 PROM – 可编程只读存储器&#xff0c;数据写入一次&#xff08;不是在制造过程中&#xff0c;而是以后的…

【论文速读】| LLM4FUZZ:利用大语言模型指导智能合约的模糊测试

本次分享论文&#xff1a;LLM4FUZZ: Guided Fuzzing of Smart Contracts with Large Language Models 基本信息 原文作者&#xff1a;Chaofan Shou, Jing Liu, Doudou Lu, Koushik Sen 作者单位&#xff1a;加州大学伯克利分校&#xff0c;加州大学欧文分校&#xff0c;Fuzz…

15 华三华为链路聚合综述

1 链路聚合简介 以太网链路聚合通过将多条以太网物理链路捆绑在一起形成一条以太网逻辑链路&#xff0c;实现增加链路带宽的目的&#xff0c;同时这些捆绑在一起的链路通过相互动态备份&#xff0c;可以有效地提高链路的可靠性。 2 成员端口的状态 聚合组内的成员端口具有以下…

2024年,Web开发新趋势!

随着我们迈入新的一年&#xff0c;现在正是审视2024年网页开发领域开始流行哪些趋势的绝佳时机。回顾2023年的一系列更新&#xff0c;以下是来年一些热门话题的概览。 自主托管有回归的趋势 近些年&#xff0c;自主托管一直是网页开发者和公司托管其应用程序的默认方式。开发…

蓝桥杯13届JAVA A组 国赛

​​​​​​​ package 蓝桥杯国赛; // 贪心选个数最少的进行摆 // 2:1 ,3:1, 4:1,5 : 3,6:3,7:1 // 选 1&#xff0c;7&#xff0c;4&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;9 // 然后都选满10个 public class 火彩棒数字 {public static void main(String[] a…

游戏行业被攻击的原因、攻击种类及合适的服务器

很多游戏刚上线没多久就频繁遭到同行恶意攻击。在相关数据报告中&#xff0c;2023年上半年遭受DDoS攻击的行业中&#xff0c;游戏行业占到40%&#xff0c;而且攻击方式、攻击频率、攻击峰值呈明显上升趋势。很多充满创意的游戏开发公司刚才开发上线一个很有特色的产品&#xff…

安卓实现视频录制与显示和翻转摄像头

权限&#xff1a; <!-- 相机权限 --> <uses-featureandroid:name"android.hardware.camera"android:required"false" /> <uses-permission android:name"android.permission.CAMERA" /><!-- 录音权限&#xff08;包括麦克…

Centos 7.9 配置VNCServer实现远程vnc连接

文章目录 1、Centos安装图形界面1.1、安装X Windows System图形界面1.2、安装GNOME图形界面 2、VNC SERVER配置2.1、VNC SERVER安装2.2、VNC SERVER配置1&#xff09;创建vnc配置文件2&#xff09;修改配置文件内容3&#xff09;完整配置文件参考 2.3、设置vnc密码2.4、配置防火…

网络编程套接字和传输层tcp,udp协议

认识端口号 我们知道在网络数据传输的时候&#xff0c;在IP数据包头部有两个IP地址&#xff0c;分别叫做源IP地址和目的IP地址。IP地址是帮助我们在网络中确定最终发送的主机&#xff0c;但是实际上数据应该发送到主机上指定的进程上的&#xff0c;所以我们不仅要确定主机&…

虚拟化技术 分离虚拟机数据流量与ESXi的流量管理

一、实验内容 为ESXi主机添加网卡通过vClient查看已添加的网卡信息为ESXi添加网络&#xff0c;创建标准交换机修改网络配置&#xff0c;实现虚拟机数据流量与ESXi的管理流量分离 二、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑&#xff0c;建…