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

Android WindowContainer窗口结构

Android窗口是根据显示屏幕来管理,每个显示屏幕的窗口层级分为37层,0-36层。每层可以放置多个窗口,上层窗口覆盖下面的。

  要理解窗口的结构,需要学习下WindowContainer、RootWindowContainer、DisplayContent、TaskDisplayArea、Task、ActivityRecord、WindowToken、WindowState

WindowContainer等类。

WindowContainer类

  为直接包含窗口或者通过孩子层级形式包含窗口的类,定义了普遍功能。它作为基类被继承,像RootWindowContainer、DisplayContent、TaskDisplayArea、Task、ActivityRecord、WindowToken、WindowState都是直接或间接的继承该类。

class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable {……// List of children for this window container. List is in z-order as the children appear on// screen with the top-most window container at the tail of the list.protected final WindowList<E> mChildren = new WindowList<E>();            ……}

窗口结构层级相关类

  先上一张没添加特色模式窗口结构图:

该图是未添加特色模式时的结构图,添加特色模式之后的结构,更复杂。

  RootWindowContainer:根窗口容器,树的根是它。通过它遍历寻找,可以找到窗口树上的窗口。它的孩子是DisplayContent。

  DisplayContent:该类是对应着显示屏幕的,Android是支持多屏幕的,所以可能存在多个DisplayContent对象。上图只画了一个对象的结构,其他对象的结构也是和画的对象的结构是相似的。

  TaskDisplayArea:它为DisplayContent的孩子,对应着窗口层次的第2层。第2层作为应用层,看它的定义:int APPLICATION_LAYER = 2,应用层的窗口是处于第2层。TaskDisplayArea的孩子是Task类,其实它的孩子类型也可以是TaskDisplayArea。而Task的孩子则可以是ActivityRecord,也可以是Task。

  Tokens:它为DisplayContent的孩子,它的孩子是WindowToken。而WindowToken的孩子则为WindowState对象。WindowState是对应着一个窗口的。结构图中,DisplayContent不止包含一个Tokens,还有两个。其实ImeContainer也是继承自Tokens。

  ImeContainer:它也为DisplayContent的孩子,它是输入法窗口的容器,它的孩子是WindowToken类型。WindowToken的孩子为WindowState类型,而WindowState类型则对应着输入法窗口。

  Task:任务,它的孩子可以是Task,也可以是ActivityRecord类型。

  ActivityRecord:是对应着应用进程中的Activity的。ActivityRecord是继承WindowToken的,它的孩子类型为WindowState。

  WindowState:WindowState是对应着一个窗口的。

  结构图中,DisplayContent有5个孩子。图中从上到下,第一个是Tokens,对应着窗口图层0、1。第二个是TaskDisplayArea,对应着窗口图层2。第三个是Tokens,对应着窗口图层3到14。第四个是ImeContainer,对应着窗口图层15到16。第五个是Tokens,对应着窗口图层17到36。

Activity添加窗口过程

@frameworks/base/core/java/android/app/ActivityOptions.java
ActivityOptions(Bundle opts) {private static final String KEY_AVOID_MOVE_TO_FRONT = "android.activity.avoidMoveToFront";mAvoidMoveToFront = opts.getBoolean(KEY_AVOID_MOVE_TO_FRONT, false);@frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
startActivityInnerSlog.w(TAG, "xww startActivityInner, targetTask=" + targetTask + " r=" + r + " sourceRecord=" + sourceRecord); //xww startActivityInner, targetTask=null r=ActivityRecord{44c341e u0 com.xxx.launcher/.MainActivity t2} sourceRecord=nullif (!mAvoidMoveToFront && mDoResume) {  mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);  }        
@frameworks/base/services/core/java/com/android/server/wm/Task.javamoveToFrontSlog.w(TAG, "xww moveToFront 3, task=" + task + " reason=" + reason);  //xww moveToFront 3, task=null reason=reuseOrNewTaskmoveToFrontInner(reason, task);
@frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.javatask.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */);Slog.w(TAG, "xww positionChildAt 3aa, child.asTask()=" + child.asTask());//xww positionChildAt 3aa, child.asTask()=Task{7862cf6 #6 type=standard A=1000:com.xxx.launcher U=0 visible=true visibleRequested=false mode=fullscreen translucent=true sz=1}positionChildTaskAt(position, child.asTask(), includingParents);if (includingParents && getParent() != null && (moveToTop || moveToBottom)) {Slog.w(TAG, "xww positionChildAt 6, this=" + this + " getParent()=" + getParent().toString());getParent().positionChildAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM, this /* child */, true /* includingParents */);
@frameworks/base/services/core/java/com/android/server/wm/DisplayArea.javaif (includingParents && parent != null && (position == POSITION_TOP || position == POSITION_BOTTOM)) {Slog.w(TAG, "xww positionChildAt 18, this=" + this);parent.positionChildAt(position, this /* child */, true /* includingParents */);
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.javacase POSITION_TOP:  Slog.w(TAG, "xww addChild 4 child=" + child.toString() + " position=" + position + " this=" + this.toString());mChildren.add(child);  //ww addChild 4 child=Display{#2 state=ON size=1920x1080 ROTATION_0 name=avd_launcher} position=2147483647 this=com.android.server.wm.RootWindowContainer@973f7ec
@frameworks/base/services/core/java/com/android/server/wm/Task.java                                            mTargetRootTask.startActivityLocked(mStartActivity, topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask, isTaskSwitch, mOptions, sourceRecord);if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {  positionChildAtTop(rTask);
@frameworks/base/services/core/java/com/android/server/wm/Task.java    moveToFront("positionChildAtTop");@frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
populateInputWindowHandle
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.javafinal boolean focusable = w.canReceiveKeys() && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());Slog.w(TAG, "xww isOnTop 3, this=" + toString() + " parent=" + (parent == null ? "null" : parent.toString()) + " parent.getTopChild()=" + (parent.getTopChild() == null ? "null" : parent.getTopChild().toString()));if(parent != null){for (int i = parent.mChildren.size() - 1; i >= 0; --i) {Object child = parent.mChildren.get(i);Slog.w(TAG, "xww isOnTop, i=" + i + ", child=" + child.toString());}}        return parent != null && parent.getTopChild() == this && parent.isOnTop();//isOnTop 3, this=Display{#3 state=ON size=1920x1080 ROTATION_0 name=avd_launcher} parent=com.android.server.wm.RootWindowContainer@bf43992 parent.getTopChild()=Display{#3 state=ON size=1920x1080 ROTATION_0 name=avd_launcher}
@frameworks/base/services/core/java/com/android/server/wm/WindowList.java        return mChildren.peekLast();return size() > 0 ? get(size() - 1) : null;
@frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.javaparent.isOnTop()   //parent=com.android.server.wm.RootWindowContainer@bf43992return true;

addWindowToken流程

@frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
addWindowToken
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.javada.addChild(token);Slog.w(TAG, "xww addChild 2 child=" + child.toString() + " this=" + this.toString());  //xww addChild 2 child=WindowToken{a0b2c76 android.os.Binder@9f68311} this=Leaf:3:14@132637315mChildren.add(positionToAdd, child);@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java        
addChildSlog.w(TAG, "xww addChild 3 child=" + child.toString() + " index=" + index + " this=" + this.toString());mChildren.add(index, child);

打印窗口信息

@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java    void FindChildInfo(E node, String indent){Slog.w(TAG, "FindMeshInfo: node=" + indent + "|--" + node + ", size=" + node.mChildren.size());if(node.mChildren.size() == 0){return;}}void FindChild(E node, String indent){indent += "|  ";FindChildInfo(node, indent);for(int i = 0; i < node.mChildren.size(); i++){FindChild((E)node.mChildren.get(i), indent);}}@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
positionChildAtswitch (position) {case POSITION_TOP:if(child.toString().contains("avd_launcher")){String str = new String();Slog.w(TAG, "xww addChild xxxxx begin");this.FindChild((E)this, str);Slog.w(TAG, "xww addChild xxxxx end");}
    FindMeshInfo: node=|  |--com.android.server.wm.RootWindowContainer@58ef5a3, size=xxxFindMeshInfo: node=|  |  |--Display{#4 state=ON size=1920x1080 ROTATION_0 name=avd_launcher}, size=4FindMeshInfo: node=|  |  |  |--WindowedMagnification:0:31@251785581, size=7FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:0:14@45167010, size=3FindMeshInfo: node=|  |  |  |  |  |--Leaf:0:1@131968563, size=0FindMeshInfo: node=|  |  |  |  |  |--DefaultTaskDisplayArea@48817648, size=1FindMeshInfo: node=|  |  |  |  |  |  |--Task{e9e1c50 #8 type=standard A=1000:com.xxx.launcher U=0 visible=true visibleRequested=false mode=fullscreen translucent=true sz=1}, size=1FindMeshInfo: node=|  |  |  |  |  |  |  |--ActivityRecord{bd29e49 u0 com.xxx.launcher/.MainActivity t8}, size=0FindMeshInfo: node=|  |  |  |  |  |--Leaf:3:14@182007657, size=0FindMeshInfo: node=|  |  |  |  |--ImePlaceholder:15:16@26527214, size=1FindMeshInfo: node=|  |  |  |  |  |--ImeContainer@79362703, size=0FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:17:23@93221148, size=1FindMeshInfo: node=|  |  |  |  |  |--Leaf:17:23@197452069, size=0FindMeshInfo: node=|  |  |  |  |--Leaf:24:25@118182650, size=0FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:26:27@175550635, size=1FindMeshInfo: node=|  |  |  |  |  |--Leaf:26:27@228557576, size=0FindMeshInfo: node=|  |  |  |  |--Leaf:28:28@117926561, size=0FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:29:31@170632390, size=1FindMeshInfo: node=|  |  |  |  |  |--Leaf:29:31@133016711, size=0FindMeshInfo: node=|  |  |  |--Leaf:32:32@36554676, size=0FindMeshInfo: node=|  |  |  |--FullscreenMagnification:33:35@160370653, size=1FindMeshInfo: node=|  |  |  |  |--Leaf:33:35@179128146, size=0FindMeshInfo: node=|  |  |  |--Leaf:36:36@49187363, size=0

@frameworks/base/core/java/android/app/ActivityOptions.java
ActivityOptions(Bundle opts) {
    private static final String KEY_AVOID_MOVE_TO_FRONT = "android.activity.avoidMoveToFront";
    mAvoidMoveToFront = opts.getBoolean(KEY_AVOID_MOVE_TO_FRONT, false);


@frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
startActivityInner
    Slog.w(TAG, "xww startActivityInner, targetTask=" + targetTask + " r=" + r + " sourceRecord=" + sourceRecord); //xww startActivityInner, targetTask=null r=ActivityRecord{44c341e u0 com.xxx.launcher/.MainActivity t2} sourceRecord=null
    if (!mAvoidMoveToFront && mDoResume) {  mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);  }        
@frameworks/base/services/core/java/com/android/server/wm/Task.java
        moveToFront
        Slog.w(TAG, "xww moveToFront 3, task=" + task + " reason=" + reason);  //xww moveToFront 3, task=null reason=reuseOrNewTask
            moveToFrontInner(reason, task);
@frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java
                task.getParent().positionChildAt(POSITION_TOP, task, true /* includingParents */);
                    Slog.w(TAG, "xww positionChildAt 3aa, child.asTask()=" + child.asTask());
                    //xww positionChildAt 3aa, child.asTask()=Task{7862cf6 #6 type=standard A=1000:com.xxx.launcher U=0 visible=true visibleRequested=false mode=fullscreen translucent=true sz=1}
                    positionChildTaskAt(position, child.asTask(), includingParents);
                        if (includingParents && getParent() != null && (moveToTop || moveToBottom)) {
                            Slog.w(TAG, "xww positionChildAt 6, this=" + this + " getParent()=" + getParent().toString());
                            getParent().positionChildAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM, this /* child */, true /* includingParents */);
@frameworks/base/services/core/java/com/android/server/wm/DisplayArea.java
                                if (includingParents && parent != null && (position == POSITION_TOP || position == POSITION_BOTTOM)) {
                                    Slog.w(TAG, "xww positionChildAt 18, this=" + this);
                                    parent.positionChildAt(position, this /* child */, true /* includingParents */);
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
                                        case POSITION_TOP:  
                                            Slog.w(TAG, "xww addChild 4 child=" + child.toString() + " position=" + position + " this=" + this.toString());
                                            mChildren.add(child);  //ww addChild 4 child=Display{#2 state=ON size=1920x1080 ROTATION_0 name=avd_launcher} position=2147483647 this=com.android.server.wm.RootWindowContainer@973f7ec
@frameworks/base/services/core/java/com/android/server/wm/Task.java                                            
    mTargetRootTask.startActivityLocked(mStartActivity, topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask, isTaskSwitch, mOptions, sourceRecord);
        if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {  positionChildAtTop(rTask);
@frameworks/base/services/core/java/com/android/server/wm/Task.java    
            moveToFront("positionChildAtTop");

@frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java
populateInputWindowHandle
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
    final boolean focusable = w.canReceiveKeys() && (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
        Slog.w(TAG, "xww isOnTop 3, this=" + toString() + " parent=" + (parent == null ? "null" : parent.toString()) + " parent.getTopChild()=" + (parent.getTopChild() == null ? "null" : parent.getTopChild().toString()));
        if(parent != null){
            for (int i = parent.mChildren.size() - 1; i >= 0; --i) {
                Object child = parent.mChildren.get(i);
                Slog.w(TAG, "xww isOnTop, i=" + i + ", child=" + child.toString());
            }
        }        
        return parent != null && parent.getTopChild() == this && parent.isOnTop();
        //isOnTop 3, this=Display{#3 state=ON size=1920x1080 ROTATION_0 name=avd_launcher} parent=com.android.server.wm.RootWindowContainer@bf43992 parent.getTopChild()=Display{#3 state=ON size=1920x1080 ROTATION_0 name=avd_launcher}
@frameworks/base/services/core/java/com/android/server/wm/WindowList.java        
            return mChildren.peekLast();
                return size() > 0 ? get(size() - 1) : null;
@frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
            parent.isOnTop()   //parent=com.android.server.wm.RootWindowContainer@bf43992
                return true;

@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java    
    void FindChildInfo(E node, String indent){
        Slog.w(TAG, "FindMeshInfo: node=" + indent + "|--" + node + ", size=" + node.mChildren.size());
        if(node.mChildren.size() == 0){
            return;
        }
    }

    void FindChild(E node, String indent){
        indent += "|  ";
        FindChildInfo(node, indent);
        for(int i = 0; i < node.mChildren.size(); i++){
            FindChild((E)node.mChildren.get(i), indent);
        }
    }
    
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
positionChildAt
    switch (position) {
    case POSITION_TOP:
        if(child.toString().contains("avd_launcher")){
                String str = new String();
                Slog.w(TAG, "xww addChild xxxxx begin");
                this.FindChild((E)this, str);
                Slog.w(TAG, "xww addChild xxxxx end");
        }

相关文章:

Android WindowContainer窗口结构

Android窗口是根据显示屏幕来管理&#xff0c;每个显示屏幕的窗口层级分为37层&#xff0c;0-36层。每层可以放置多个窗口&#xff0c;上层窗口覆盖下面的。 要理解窗口的结构&#xff0c;需要学习下WindowContainer、RootWindowContainer、DisplayContent、TaskDisplayArea、T…...

从零到一实现微信小程序计划时钟:完整教程

在本教程中&#xff0c;我们将一起实现一个微信小程序——计划时钟。这个小程序的核心功能是帮助用户添加任务、设置任务的时间范围&#xff0c;并且能够删除和查看已添加的任务。通过以下步骤&#xff0c;我们将带你从零开始实现一个具有基本功能的微信小程序计划时钟。 项目…...

moveable 一个可实现前端海报编辑器的 js 库

目录 缘由-胡扯本文实验环境通用流程1.基础移动1.1 基础代码1.1.1 data-* 解释 1.2 操作元素创建1.3 css 修饰1.4 cdn 引入1.5 js 实现元素可移动1.6 图片拖拽2.缩放3.旋转4.裁剪 懒得改文案了&#xff0c;海报编辑器换方案了&#xff0c;如果后面用别的再更。 缘由-胡扯 导火…...

wangEditor 编辑器 Vue 2.0 + Nodejs 配置

资料 Vue2.0 版本的安装&#xff1a;https://www.wangeditor.com/v5/for-frame.html#%E4%BD%BF%E7%94%A8上传图片配置&#xff1a;https://www.wangeditor.com/v5/menu-config.html#%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87 安装步骤 1.安装界面基础部分 <!-- 富文本编辑器…...

DeepSeek R1生成图片总结2(虽然本身是不能直接生成图片,但是可以想办法利用别的工具一起实现)

DeepSeek官网 目前阶段&#xff0c;DeepSeek R1是不能直接生成图片的&#xff0c;但可以通过优化文本后转换为SVG或HTML代码&#xff0c;再保存为图片。另外&#xff0c;Janus-Pro是DeepSeek的多模态模型&#xff0c;支持文生图&#xff0c;但需要本地部署或者使用第三方工具。…...

x86平台基于Qt+opengl优化ffmpeg软解码1080P视频渲染效率

一般的在arm嵌入式平台&#xff0c;大多数板子都要硬解码硬件渲染的框架&#xff0c;使用即可。 在x86下比较麻烦了。 优化的思路一共有以下几个方面&#xff0c; 1. 软解码变成硬解码 2. 将YUV转QImage的操作转移到GPU 3. QWidget渲染QImage变成opengGL渲染AVFrame 这三点…...

机器学习入门-读书摘要

先看了《深度学习入门&#xff1a;基于python的理论和实践》这本电子书&#xff0c;早上因为入迷还坐过站了。。 因为里面的反向传播和链式法则特别难懂&#xff0c;又网上搜了相关内容进行进一步理解&#xff0c;参考的以下文章&#xff08;个人认为都讲的都非常好&#xff0…...

前端【技术方案】重构项目

1. 明确重构目标 优化性能 减少页面加载时间降低资源占用 提升代码可维护性 更规范的代码风格更清晰的代码结构更明确的模块设计 扩展功能 为项目添加新功能改进现有功能 2. 评估项目现状 审查代码 全面检查现有代码&#xff0c;找出代码中的问题&#xff0c;如代码冗余、耦合…...

大语言模型简史:从Transformer(2017)到DeepSeek-R1(2025)的进化之路

2025年初&#xff0c;中国推出了具有开创性且高性价比的「大型语言模型」&#xff08;Large Language Model — LLM&#xff09;DeepSeek-R1&#xff0c;引发了AI的巨大变革。本文回顾了LLM的发展历程&#xff0c;起点是2017年革命性的Transformer架构&#xff0c;该架构通过「…...

RabbitMQ服务异步通信

消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; 1. 消息可靠性 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送时丢失&#xff1a; 生…...

Python常见面试题的详解7

1. 内置的数据结构有哪几种 Python 中有多种内置的数据结构&#xff0c;主要分为以下几种&#xff1a; 1.1 数值类型 整数&#xff08;int&#xff09;&#xff1a;用于表示整数&#xff0c;没有大小限制。例如&#xff1a;1, -5, 100。浮点数&#xff08;float&#xff09;…...

Django REST Framework (DRF) 中用于构建 API 视图类解析

Django REST Framework (DRF) 提供了丰富的视图类&#xff0c;用于构建 API 视图。这些视图类可以分为以下几类&#xff1a; 1. 基础视图类 这些是 DRF 中最基础的视图类&#xff0c;通常用于实现自定义逻辑。 常用类 APIView&#xff1a; 最基本的视图类&#xff0c;所有其…...

Huatuo热更新--安装HybridCLR

1.自行安装unity编辑器 支持2019.4.x、2020.3.x、2021.3.x、2022.3.x 中任一版本。推荐安装2019.4.40、2020.3.26、2021.3.x、2022.3.x版本。 根据你打包的目标平台&#xff0c;安装过程中选择必要模块。如果打包Android或iOS&#xff0c;直接选择相应模块即可。如果你想打包…...

读书笔记 - 修改代码的艺术

读书笔记 - 修改代码的艺术 第 1 章 修改软件第 2 章 带着反馈工作系统变更方式反馈方式遗留代码修改方法 第 3 章 感知和分离伪协作程序模拟对象 第 4 章 接缝模型接缝 第 5 章 工具自动化重构工具单元测试用具 第 6 章 时间紧迫&#xff0c;但必须修改新生方法&#xff08;Sp…...

【Go并发编程】Goroutine 调度器揭秘:从 GMP 模型到 Work Stealing 算法

每天一篇Go语言干货&#xff0c;从核心到百万并发实战&#xff0c;快来关注魔法小匠&#xff0c;一起探索Go语言的无限可能&#xff01; 在 Go 语言中&#xff0c;Goroutine 是一种轻量级的并发执行单元&#xff0c;它使得并发编程变得简单高效。而 Goroutine 的高效调度机制是…...

c# -01新属性-模式匹配、弃元、析构元组和其他类型

文章目录 **学习摘抄分享**模式匹配概述Null 检查类型测试比较离散值关系模型多个输入ObServation列表模式弃元元组和对象析构利用switch的模式进行匹配对于out的方法调用独立弃元析构元组和其他类型元组方法一方法二方法三方法四使用弃元元组的元素使用弃元的用户定义类型解构…...

同步异步日志系统-日志落地模块的实现

功能&#xff1a;将格式化完成后的日志消息字符串&#xff0c;输出到指定的位置 扩展&#xff1a;支持同时将日志落地到不同的位置 位置分类&#xff1a; 1.标准输出 2.指定文件&#xff08;时候进行日志分析&#xff09; 3.滚动文件&#xff08;文件按照时间/大小进行滚动…...

LabVIEW 天然气水合物电声联合探测

天然气水合物被认为是潜在的清洁能源&#xff0c;其储量丰富&#xff0c;预计将在未来能源格局中扮演重要角色。由于其独特的物理化学特性&#xff0c;天然气水合物的探测面临诸多挑战&#xff0c;涉及温度、压力、电学信号、声学信号等多个参数。传统的人工操作方式不仅效率低…...

类型通配符上限

主函数 package typeWildcardTop;import java.util.ArrayList;public class typeWildcardTopTest {/**/public static void main(String[] args) { // test1();test2();}/*测试showList接收ArrayList类型 ArrayList接收各种类型参数创建animals cats mincats集合 传入s…...

嵌入式音视频开发(二)ffmpeg音视频同步

系列文章目录 嵌入式音视频开发&#xff08;零&#xff09;移植ffmpeg及推流测试 嵌入式音视频开发&#xff08;一&#xff09;ffmpeg框架及内核解析 嵌入式音视频开发&#xff08;二&#xff09;ffmpeg音视频同步 嵌入式音视频开发&#xff08;三&#xff09;直播协议及编码器…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...