1 桌面壁纸

入门课,实战课,跨进程专题,input专题
ps需要学习深入framework课程和课程优惠
新课程优惠获取请加入qq群:422901085

先看桌面情况下壁纸,这个情况应该属于我们最为熟悉的,那么就不用多说,大概就是因为桌面Activity的配置主题xml设置一个类似showallpaper的属性既可以,就可以让桌面后面显示壁纸了

2 aosp编译后版本锁屏后点亮屏幕也可以看到桌面壁纸(注意这里还不是专门锁屏壁纸)
大家发现锁屏点亮后确实看到的壁纸和桌面的壁纸一模一样

3 疑惑

这里是不是大家就开始比较疑惑了,请问普通Activity是通过属性配置的,而且壁纸窗口又是在wms属于最底层的状态,他依附于桌面这个可以理解,但是为啥锁屏时候又可以看到壁纸呢?锁屏理论上也只是一个window盖在最顶层,理论即使这个锁屏window透明,那么透看到的也是有桌面Activity的情况,但现实情况是我们只看到了壁纸,并没有看到桌面

针对以上的疑惑,那接下来我们就需要去解答这个疑惑。
首先我们知道壁纸属于系统中一个特殊窗口,一直处于系统最底层。这个窗口在系统中有专门类进行他的显示情况,那就我们的WallpaperController类
这个WallpaperController.java中有log打印,但需要我们将对应标志位给设置一下:

if (DEBUG_WALLPAPER) {Slog.v(TAG, "Wallpaper visibility: " + visible + " at display "+ mDisplayContent.getDisplayId());
}

这里我们把DEBUG_WALLPAPER就可以把log打开了

10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{60c77f1 u0 ScreenDecorOverlayBottom}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{df0a78b u0 ScreenDecorOverlay}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{b7a35a u0 NavigationBar0}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Win Window{3cd76e8 u0 NotificationShade}: isOnScreen=true mDrawState=4
10-23 22:55:41.115  5313  6475 V WindowManager: Found wallpaper target: Window{3cd76e8 u0 NotificationShade}
10-23 22:55:41.115  5313  6475 V WindowManager: New wallpaper target: Window{3cd76e8 u0 NotificationShade} prevTarget: null
10-23 22:55:41.116  5313  6475 V WindowManager: Report new wp offset Window{803c2b8 u0 com.android.systemui.ImageWallpaper} x=0.0 y=0.5 zoom=0.0
10-23 22:55:41.116  5313  6475 V WindowManager: Wallpaper visibility: true at display 0
10-23 22:55:41.116  5313  6475 D WindowManager: Wallpaper token android.os.Binder@3a6eda2 visible=true
10-23 22:55:41.118  5313  6475 D WindowManager: New wallpaper: target=Window{3cd76e8 u0 NotificationShade} prev=null
10-23 22:55:41.163  5313  5313 D WindowManager: powerPress: eventTime=118823847 interactive=true count=0 beganFromNonInteractive=true mShortPressOnPowerBehavior=1

打开后我们点亮锁屏和在桌面锁屏发现都有类似以下打印
WindowManager: Found wallpaper target: Window{3cd76e8 u0 NotificationShade}
看名字大家大概就知道这个log是在寻找一个wallpaper target:,而且找到的是NotificationShade即锁屏窗口
前面疑惑中就写到正常应该是桌面
10-24 00:18:50.543 10429 10450 V WindowManager: Found wallpaper target: Window{8d79f3 u0 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher}
这日志其实就可以给我们非常重要线索,可以找出对应代码在哪

 private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {if ((w.mAttrs.type == TYPE_WALLPAPER)) {if (mFindResults.topWallpaper == null || mFindResults.resetTopWallpaper) {mFindResults.setTopWallpaper(w);mFindResults.resetTopWallpaper = false;}return false;}mFindResults.resetTopWallpaper = true;if (mService.mAtmService.getTransitionController().getTransitionPlayer() == null) {if (w.mActivityRecord != null && !w.mActivityRecord.isVisible()&& !w.mActivityRecord.isAnimating(TRANSITION | PARENTS)) {// If this window's app token is hidden and not animating, it is of no interest.if (DEBUG_WALLPAPER) Slog.v(TAG, "Skipping hidden and not animating token: " + w);return false;}} else {if (w.mActivityRecord != null && !w.mActivityRecord.isVisibleRequested()) {// An activity that is not going to remain visible shouldn't be the target.return false;}}if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()+ " mDrawState=" + w.mWinAnimator.mDrawState + " w.mWillReplaceWindow = " + w.mWillReplaceWindow);if (w.toString().contains("NotificationShade")) {Slog.v(TAG, "1111 Win " + w + ": isOnScreen=" + w.isOnScreen()+ " mDrawState=" + w.mWinAnimator.mDrawState + " w.mWillReplaceWindow = " + w.mWillReplaceWindow);}if (w.mWillReplaceWindow && mWallpaperTarget == null&& !mFindResults.useTopWallpaperAsTarget) {// When we are replacing a window and there was wallpaper before replacement, we want to// keep the window until the new windows fully appear and can determine the visibility,// to avoid flickering.mFindResults.setUseTopWallpaperAsTarget(true);}final WindowContainer animatingContainer = w.mActivityRecord != null? w.mActivityRecord.getAnimatingContainer() : null;final boolean keyguardGoingAwayWithWallpaper = (animatingContainer != null&& animatingContainer.isAnimating(TRANSITION | PARENTS)&& AppTransition.isKeyguardGoingAwayTransitOld(animatingContainer.mTransit)&& (animatingContainer.mTransitFlags& TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);boolean needsShowWhenLockedWallpaper = false;if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0&& mService.mPolicy.isKeyguardLocked()&& (mService.mPolicy.isKeyguardOccluded()|| mService.mPolicy.isKeyguardUnoccluding())) {// The lowest show when locked window decides whether we need to put the wallpaper// behind.needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)|| (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());}if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {// Keep the wallpaper during Keyguard exit but also when it's needed for a// non-fullscreen show when locked activity.mFindResults.setUseTopWallpaperAsTarget(true);}final RecentsAnimationController recentsAnimationController =mService.getRecentsAnimationController();final boolean animationWallpaper = animatingContainer != null&& animatingContainer.getAnimation() != null&& animatingContainer.getAnimation().getShowWallpaper();final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;final boolean isRecentsTransitionTarget = (recentsAnimationController != null&& recentsAnimationController.isWallpaperVisible(w));if (isRecentsTransitionTarget) {if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);mFindResults.setWallpaperTarget(w);return true;} else if (hasWallpaper && w.isOnScreen()&& (mWallpaperTarget == w || w.isDrawFinishedLw())) {if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);mFindResults.setWallpaperTarget(w);if (w == mWallpaperTarget && w.isAnimating(TRANSITION | PARENTS)) {// The current wallpaper target is animating, so we'll look behind it for// another possible target and figure out what is going on later.if (DEBUG_WALLPAPER) Slog.v(TAG,"Win " + w + ": token animating, looking behind.");}// Found a target! End search.return true;}return false;};

上面最关键判断代码:

if (hasWallpaper && w.isOnScreen()&& (mWallpaperTarget == w || w.isDrawFinishedLw()))

这里的 hasWallpaper非常关键

final boolean hasWallpaper = w.hasWallpaper() || animationWallpaper;

主要调用是WindowState的方法

boolean hasWallpaper() {return (mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0|| (mActivityRecord != null && mActivityRecord.hasWallpaperBackgroudForLetterbox());
}

这里其实也就是判断window中是否有FLAG_SHOW_WALLPAPER属性,而且经过额外加log打印发现hasWallpaper值变化在锁屏window解锁前后

那么其实我们可以猜测是不是锁屏window会去动态改变自己的FLAG_SHOW_WALLPAPER属性,在有桌面显示时候锁屏的window实际是没有这个属性,在锁屏状态下是有这个属性。根据猜想去systemui代码中grep相关FLAG_SHOW_WALLPAPER关键字
果然发现有如下:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java

   private void applyKeyguardFlags(State state) {final boolean scrimsOccludingWallpaper =state.mScrimsVisibility == ScrimController.OPAQUE || state.mLightRevealScrimOpaque;final boolean keyguardOrAod = state.mKeyguardShowing|| (state.mDozing && mDozeParameters.getAlwaysOn());if ((keyguardOrAod && !state.mBackdropShowing && !scrimsOccludingWallpaper)|| mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()) {// Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a// solid backdrop or scrim. Also, show it if we are currently animating between the// keyguard and the surface behind the keyguard - we want to use the wallpaper as a// backdrop for this animation.mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;} else {mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;}

这里其实就是代表有锁屏时候需要有 mLpChanged.flags |= LayoutParams.FLAG_SHOW_WALLPAPER;
锁屏退出时清除锁屏的FLAG_SHOW_WALLPAPER
mLpChanged.flags &= ~LayoutParams.FLAG_SHOW_WALLPAPER;

Android 12中系统Wallpaper详解1--锁屏透看壁纸和桌面透看壁纸的切换相关推荐

  1. Android设置中“强行停止”详解

    Android设置中"强行停止"详解 最近工作上遇到了广播接受不到的问题,查看了<Android 开发艺术探索>一书中关于广播的发送和接受的章节(P356-P362). ...

  2. Android Studio中Gradle使用详解

    转自:http://www.jianshu.com/p/02cb9a0eb2a0 一)基本配置 build配置 buildscript {repositories {jcenter() }depend ...

  3. Android 12.0系统默认设置屏幕永不息屏

    目录 1.概述 2. 系统默认设置屏幕永不休眠功能代码 3. 系统默认设置屏幕永不休眠功能分析和功能实现

  4. 《Android Studio应用开发实战详解》——第1章,第1.2节Android系统基础

    本节书摘来自异步社区<Android Studio应用开发实战详解>一书中的第1章,第1.2节Android系统基础,作者 王翠萍,更多章节内容可以访问云栖社区"异步社区&quo ...

  5. Android 系统(252)---Android:BLE智能硬件开发详解

    Android:BLE智能硬件开发详解 目录 前言 BLE是个什么鬼 BLE中的角色分工 主要的关键词和概念  GATT(Generic Attribute Profile ) Characteris ...

  6. android调webview的方法,Android中的WebView详解

    Android中的WebView详解 WebView详解 基本用法 布局文件配置WebView android:id="@+id/wv_news_detail" android:l ...

  7. android中oncreate方法,android开发之onCreate( )方法详解

    这里我们只关注一句话:This is where you should do all of your normal static set up.其中我们只关注normal static, normal ...

  8. libraries 和android runtime之间的关系,《Android Studio应用开发实战详解》——第1章,第1.3节Android系统架构...

    本节书摘来自异步社区<Android Studio应用开发实战详解>一书中的第1章,第1.3节Android系统架构,作者 王翠萍,更多章节内容可以访问云栖社区"异步社区&quo ...

  9. 《Android Studio应用开发实战详解》——第1章,第1.1节移动智能设备系统发展现状...

    本节书摘来自异步社区<Android Studio应用开发实战详解>一书中的第1章,第1.1节移动智能设备系统发展现状,作者 王翠萍,更多章节内容可以访问云栖社区"异步社区&qu ...

  10. Android 中malloc_debug 原理详解

    版本基于:Android R 关联博文: Android 中malloc_debug 使用详解 0. 前言 最近上项目中遇到一个native 可能内存泄漏的问题,曾考虑使用HWASAN,但这个工具是针 ...

最新文章

  1. mysql 将三个月的数据导到历史表_迁移数据到历史表,减少业务表中数据压力 Mysql...
  2. 利用Java的BigDecimal与马青公式精确计算π后10000位,
  3. python3列表生成式中的for循环与普通放在外面的for循环细微差异
  4. MyEclipse的Debug模式启动缓慢
  5. 真搞不懂这些部门大学为什么要迁户口?
  6. linux内核ttyusb实现,[zhuan]Linux的USB-Serial驱动(从系统初始化到生成tty设备的全过程)...
  7. ACM-ICPC 2018 南京赛区网络预赛 Lpl and Energy-saving Lamps 线段树
  8. 解决setInterval计时器不准的问题
  9. html 盒子写法,CSS盒子模型
  10. 是否允许此网站打开你计算机上的程序
  11. 酒桌游戏c语言,拯救冷场,这十三款经典酒桌游戏你玩过几个?
  12. STM32控制SG90舵机与超声波HC_SR04测距模块
  13. zkteco iface702 中控考勤机java开发步骤一---连接考勤机
  14. C#串口编程基础入门
  15. 坚果pro android版本,坚果Pro有几个版本 哪个版本好?坚果Pro各版本的区别
  16. mac android studio Waiting for application to come online解决方案
  17. 搭建Openstack环境以及Openstack认证服务
  18. 2021virtualbox中Ubuntu16.04:开发环境配置,更换源
  19. 不要让回忆有负疚感——职业规划法则一
  20. java 鼠标点击按钮事件_Java 鼠标点击事件实例

热门文章

  1. 在vue中简单使用Luckysheet
  2. 用java写图形验证码,超级简单
  3. css电子表数字,使用css实现电子数字效果
  4. python numpy安装教程_python 环境下安装 numpy
  5. 《应用时间序列分析:R软件陪同》——1.3 R软件入门
  6. Vivado ML 2021.1 安装包下载
  7. 3D建模的通用文件格式
  8. python 数学公式_pythonp_word03公式编辑器,空心方阵公式,高中数学必修一公式,销售利润率公式,高一物理必修1公式...
  9. groovy 打印json_groovyJSON - Groovy教程
  10. switch 大气层双系统 进入破解系统 及安装nsp nsz 格式教程