android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计-千里马framework实战

news2024/10/1 15:22:20

hi,粉丝朋友们!
今天有个学员朋友,问到了一个高斯模糊相关问题,这个高斯模糊相关的需求我相对还是比较熟悉,下面来重点讲解一下新版本高斯模糊相关的实现。
更多framework干货知识手把手教学

Log.i("qq群",“422901085);

1、高斯模糊应用场景

在这里插入图片描述

状态栏下拉时候可以看到桌面的画面作为背景,但是这个时候桌面的画面却是被高斯模糊的,这样给人交互体验上就有一个很大提升,美观层度和主次分明,就像拍照时候的人物一样,会把背景等模糊,把人物作为重点。

2、高斯模糊实现方案

在这里插入图片描述

方案1 截图这种属于最为常规的方案,以前都采用该方案,主要实现原理也很简单:
对背景截图 —》 对截图bitmap进行高斯模糊图像处理 —》把处理后的bitmap作为背景展示
优点:方案简单,属于所有模糊等都是自己控制,控制灵活性大
缺点:因为截图,所以没办法搞成实时模糊,实现功能修改逻辑较多

方案2 这个是新版本android才有的自带方法,它的实现原理,对某一个window进行flag的设置,如果设置了FLAG_BLUR_BEHIND,那么它后面的window层就会被设置成模糊,属于surfaceflinger层面实现了,在渲染时候layer处理,这个模糊属于实时的,即后面画面哪怕在动,高斯模糊也跟着动
优点:属于系统提供的接口相关,简单设置即可以,不需要自己额外操作,可以实时模糊

缺点:因为操作对象是window,只是窗口下面的会被模糊,导致一些窗口切换场景可能会有bug
下面我们就来重点介绍一下

3、重点介绍新方案2 FLAG_BLUR_BEHIND 使用

frameworks/base/core/java/android/view/WindowManager.java

   /** Window flag: enable blur behind for this window. */
    public static final int FLAG_BLUR_BEHIND        = 0x00000004;

这个FLAG_BLUR_BEHIND属于LayoutParams
在这里插入图片描述

注释就是说FLAG_BLUR_BEHIND就会让在该window下面的window进行模糊
具体如果要使用:
其实就是对window的LayoutParams设置这个flag

 getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

同时还有另一个方法setBlurBehindRadius

 public void setBlurBehindRadius(@IntRange(from = 0) int blurBehindRadius) {
            mBlurBehindRadius = blurBehindRadius;
        }

大家都知道高斯模糊都有一个模糊滤镜,这代表模糊的程度,一般mBlurBehindRadius越大模糊层度越厉害。代码如下:

 @Override
    protected void onResume() {
        super.onResume();
        
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
        getWindow().getAttributes().setBlurBehindRadius(100);//设置大一点为100,看的明显
    }

模糊前后效果对比如下:
模糊前:
在这里插入图片描述

模糊后:
在这里插入图片描述

4、原理源码分析

设置了FLAG_BLUR_BEHIND后,最后在WindowState会进行读取和相关业务处理:
frameworks/base/services/core/java/com/android/server/wm/WindowState.java


    private boolean shouldDrawBlurBehind() {
        return (mAttrs.flags & FLAG_BLUR_BEHIND) != 0
            && mWmService.mBlurController.getBlurEnabled();
    }

然后在applyDims方法中根据这个进行相关的执行:


    private void applyDims() {
        if (!mAnimatingExit && mAppDied) {
            mIsDimming = true;
            getDimmer().dimAbove(getSyncTransaction(), this, DEFAULT_DIM_AMOUNT_DEAD_WINDOW);
        } else if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || shouldDrawBlurBehind())
                   && isVisibleNow() && !mHidden) {
            // Only show the Dimmer when the following is satisfied:
            // 1. The window has the flag FLAG_DIM_BEHIND or blur behind is requested
            // 2. The WindowToken is not hidden so dims aren't shown when the window is exiting.
            // 3. The WS is considered visible according to the isVisible() method
            // 4. The WS is not hidden.
            mIsDimming = true;
            final float dimAmount = (mAttrs.flags & FLAG_DIM_BEHIND) != 0 ? mAttrs.dimAmount : 0;
            final int blurRadius = shouldDrawBlurBehind() ? mAttrs.getBlurBehindRadius() : 0;
            getDimmer().dimBelow(getSyncTransaction(), this, dimAmount, blurRadius);
        }
    }

下面来看这个 getDimmer().dimBelow方法执行:

 void dimBelow(SurfaceControl.Transaction t, WindowContainer container, float alpha,
                  int blurRadius) {
        dim(t, container, -1, alpha, blurRadius);//调用dim方法
    }
      private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer,
            float alpha, int blurRadius) {
        final DimState d = getDimState(container);//这里比较关键需要创建对应EffectLayer

        if (d == null) {
            return;
        }

        if (container != null) {
            // The dim method is called from WindowState.prepareSurfaces(), which is always called
            // in the correct Z from lowest Z to highest. This ensures that the dim layer is always
            // relative to the highest Z layer with a dim.
            t.setRelativeLayer(d.mDimLayer, container.getSurfaceControl(), relativeLayer);
        } else {
            t.setLayer(d.mDimLayer, Integer.MAX_VALUE);
        }
        t.setAlpha(d.mDimLayer, alpha);
        t.setBackgroundBlurRadius(d.mDimLayer, blurRadius);//对这个图层进行BlurRadius设置

        d.mDimming = true;
    }

这里来重点看看getDimState看看是怎么创建的:

 /**
     * Retrieve the DimState, creating one if it doesn't exist.
     */
    private DimState getDimState(WindowContainer container) {
        if (mDimState == null) {
            try {
                final SurfaceControl ctl = makeDimLayer();//这里又调用makeDimLayer创建
                mDimState = new DimState(ctl);
                /**
                 * See documentation on {@link #dimAbove} to understand lifecycle management of
                 * Dim's via state resetting for Dim's with containers.
                 */
                if (container == null) {
                    mDimState.mDontReset = true;
                }
            } catch (Surface.OutOfResourcesException e) {
                Log.w(TAG, "OutOfResourcesException creating dim surface");
            }
        }

        mLastRequestedDimContainer = container;
        return mDimState;
    }
  private SurfaceControl makeDimLayer() {
        return mHost.makeChildSurface(null)
                .setParent(mHost.getSurfaceControl())//这里host就是我们activity的task
                .setColorLayer()//注意是这种类型的layer
                .setName("Dim Layer for - " + mHost.getName())
                .setCallsite("Dimmer.makeDimLayer")
                .build();
    }

上面代码层面分析后,来看看SurfaceFlinger相关图层有啥变化
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[230528] 托福阅读真题|TPO66 13/30|整卷得分22/30|9:45~10:45|15:40~16:40

The Actor and the Audience P1 rehearsev 排练;排演anticipate v 预期;预料;预见 audiencen 观众brilliantadj 灿烂的;绝妙的rehearsaln 排练;预演;排演crumblev 崩塌stage frightn 怯场(演员…

自动化测试框架?这应该是全网最全自动化框架总结了,你要的都有...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 Python自动化测试&…

学术加油站|基于LSM-tree存储系统的内存管理,最大限度降低I/O成本

本文系北京理工大学科研助理牛颂登所著,本篇也是 OceanBase 学术系列稿件第 10 篇。欢迎访问 OceanBase 官网获取更多信息:https://www.oceanbase.com/ 「牛颂登:北京理工大学科研助理,硕士期间在电子科技大学网络空间安全研究院从…

资深老鸟总结,Selenium自动化测试实战小技巧,不要再走弯路了...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 Selenium4自动化测…

数据库小技能:数据报表

文章目录 I 需求1.1 补贴II 实现思路2.1 生成资金调节报表数据III Dto3.1 报表基本查询IV 接口I 需求 代理商调节活动汇总商户调节活动汇总激励金日月汇总数据源:活动流水表(上游回调) 1.1 补贴 调节活动补贴= D0补贴+T1补贴。(比如交易金额满足1000,转T1) 补贴金额 =…

图扑数字孪生智慧灯杆,“多杆合一”降本增效

前言 随着智慧城市建设的不断深入,智慧灯杆作为城市基础设施的重要组成部分,正在成为城市智能化和绿色化的重要手段之一。 效果展示 图扑智慧灯杆系统在城市道路照明领域引入信息化手段,通过构建路灯物联网,实现了现代化的路灯按…

线性代数 --- Gram-Schmidt, 格拉姆-施密特正交化(下)

Gram-Schmidt正交化过程 到目前为止,我们都是在反复强调“对于无解的方程组Axb而言,如果矩阵A是标准正交矩阵的话,就怎么怎么好了。。。。”。因为,不论是求投影还是计算最小二乘的正规方程,他们都包含了。当A为标准正…

yolov4论文解读

数据层面上的数据增强 四张照片拼接成一张进行训练 相当于增大了batch-size,更适合于单GPU。 Mosaic data augmentation 马赛克数据增强 self-adversarial training(SAT) 自我对抗训练 DropBlock Label Smoothing 损失函数 由IOU改进到CIOU 网络结构 CSPNet&…

Win10 WLAN驱动正常但仍然不显示无线网络解决办法

Win10 WLAN驱动正常但仍然不显示无线网络解决办法 写作背景过程解决方案结尾 写作背景 本菜鸡重置了电脑的网络,然后重新启动后 WLAN 不见了,连不了 WIFI 了,很疑惑,后来经过一番搜索找到了问题所在,写下本篇文章以记…

Spark/Flink广播实现作业配置动态更新

前言 在实时计算作业中,往往需要动态改变一些配置,举几个栗子: 实时日志ETL服务,需要在日志的格式、字段发生变化时保证正常解析;实时NLP服务,需要及时识别新添加的领域词与停用词;实时风控服…

访问学者J1签证面签的七个问题

作为访问学者,申请J1签证面签时可能会遇到一些常见问题。下面知识人网小编将介绍七个访问学者面签可能遇到的问题,并提供相应的答案。 问题一:您将在美国进行何种类型的学术研究? 答案:我将在美国从事学术研究&#x…

普冉PY32L020单片机简介,主频最高48MHZ

PY32L020单片机是一颗32 位 ARM Cortex-M0内核,宽电压工作范围的 MCU。这颗MCU的价格跟八位单片机相差不大,性价比可以说是非常的高了。来看看PY32L020的配置吧。 PY32L020单片机产品特性: 内核: — 32 位 ARM Cortex - M0 — 最…

飞浆AI studio人工智能课程学习(2)-Prompt优化思路|十个技巧高效优化Prompt|迭代法|Trick法|通用法|工具辅助

文章目录 优化思路上节课的例子问题分析思路解析 Prompt优化技巧Prompt优化原理 十个技巧高效优化Prompt迭代法Trick法工具法通用技巧│定基础通用技巧│做强调需求强调怎么做? 通用技巧│提预设Trick法│戴高帽原理 Trick法│说好话以基础计算为例: Trick法│给提示…

小红书数据分析:如何用ChatGPT输出爆文笔记

ChatGPT的热度依旧不减,随着技术升级,越来越多更高级的玩法被发掘。今天我们就来聊聊,如何用ChatGPT写出小红书风格的文章。 首先,小红书笔记制作分为两个步骤: 1、找选题 2、写小红书风格的笔记 我们用例子说话&a…

全国自考本科通过率仅7%,为什么还有这么多人报考?

根据教育部官网公布的《2021年全国教育事业发展统计公报》得知:2021年,全国高等教育自学考试学历教育报考625.78万人次,取得毕业证书48.94万人。也就是说2021年我国自考平均通过率大概在7%左右。 自考通过率为什么这么低? ①自考…

Android平台外部编码数据(H264/H265/AAC/PCMA/PCMU)实时预览播放技术实现

开发背景 好多开发者可能疑惑,外部数据实时预览播放,到底有什么用? 是的,一般场景是用不到的,我们在开发这块前几年已经开发了非常稳定的RTMP、RTSP直播播放模块,不过也遇到这样的场景,部分设…

“ChatGPT之父”勇闯币圈!数十亿人的空投计划,只需交出你的虹膜?

最近,Worldcoin(世界币)热度持续提升,这个由OpenAI创始人SamAltman亲自操持的加密项目,让沉寂已久的币圈开始躁动起来。 虽然Worldcoin并非最新项目,但颇具乌托邦色彩的理念,独特的虹膜识别机制…

10几个国产免费ChatGPT网页版(内附体验网址)

文章目录 前言1. AI文本工具站效率工具自媒体创作工具代码工具 2.道和顺ChatIC3.星期五4.文心一言5.讯飞星火认知大模型6.通义千问7.商汤-日日新8.Moss9.ChatGLM10. 360智脑写在最后 前言 随着ChatGPT迅速走红,国内各大企业纷纷发力认知大模型领域。经过一段时间的酝酿&#x…

剩余参数、扩展运算符、将伪数组转换伪数组

剩余参数 剩余参数语法允许我们将一个不定数量的参数表示为一个数组 语法: array.forEach(function(currentValue,index,arr){}) currentValue:数组当前项的值index:数组当前项的索引arr:数组对象本身 示例 <!DOCTYPE html> <html lang"en"><h…

实力认证!开源网安入选《2023年中国网络安全市场全景图》

近日&#xff0c;数说安全正式发布《2023年中国网络安全市场全景图》&#xff08;以下简称全景图&#xff09;。开源网安凭借强大的技术能力与服务经验上榜本次全景图开发安全/DevSecOps、应用安全测试&#xff08;AST&#xff09;、软件成分分析&#xff08;SCA&#xff09;、…