Android WindowContainer窗口结构

news2025/2/21 4:29:02

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
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;

addWindowToken流程

@frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
addWindowToken
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
    da.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@132637315
        mChildren.add(positionToAdd, child);
 
               
@frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java        
addChild
    Slog.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
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");
        }
    FindMeshInfo: node=|  |--com.android.server.wm.RootWindowContainer@58ef5a3, size=xxx
    FindMeshInfo: node=|  |  |--Display{#4 state=ON size=1920x1080 ROTATION_0 name=avd_launcher}, size=4
    FindMeshInfo: node=|  |  |  |--WindowedMagnification:0:31@251785581, size=7
    FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:0:14@45167010, size=3
    FindMeshInfo: node=|  |  |  |  |  |--Leaf:0:1@131968563, size=0
    FindMeshInfo: node=|  |  |  |  |  |--DefaultTaskDisplayArea@48817648, size=1
    FindMeshInfo: node=|  |  |  |  |  |  |--Task{e9e1c50 #8 type=standard A=1000:com.xxx.launcher U=0 visible=true visibleRequested=false mode=fullscreen translucent=true sz=1}, size=1
    FindMeshInfo: node=|  |  |  |  |  |  |  |--ActivityRecord{bd29e49 u0 com.xxx.launcher/.MainActivity t8}, size=0
    FindMeshInfo: node=|  |  |  |  |  |--Leaf:3:14@182007657, size=0
    FindMeshInfo: node=|  |  |  |  |--ImePlaceholder:15:16@26527214, size=1
    FindMeshInfo: node=|  |  |  |  |  |--ImeContainer@79362703, size=0
    FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:17:23@93221148, size=1
    FindMeshInfo: node=|  |  |  |  |  |--Leaf:17:23@197452069, size=0
    FindMeshInfo: node=|  |  |  |  |--Leaf:24:25@118182650, size=0
    FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:26:27@175550635, size=1
    FindMeshInfo: node=|  |  |  |  |  |--Leaf:26:27@228557576, size=0
    FindMeshInfo: node=|  |  |  |  |--Leaf:28:28@117926561, size=0
    FindMeshInfo: node=|  |  |  |  |--FullscreenMagnification:29:31@170632390, size=1
    FindMeshInfo: node=|  |  |  |  |  |--Leaf:29:31@133016711, size=0
    FindMeshInfo: node=|  |  |  |--Leaf:32:32@36554676, size=0
    FindMeshInfo: node=|  |  |  |--FullscreenMagnification:33:35@160370653, size=1
    FindMeshInfo: node=|  |  |  |  |--Leaf:33:35@179128146, size=0
    FindMeshInfo: 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");
        }

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

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

相关文章

2025年最新版1688平台图片搜索接口技术指南及Python实现

随着电商行业的蓬勃发展&#xff0c;1688作为国内领先的B2B交易平台&#xff0c;其商品搜索功能对于买家和卖家而言都至关重要。图片搜索作为其中的一种高级搜索方式&#xff0c;能够极大地提升用户的搜索体验和准确性。本文将详细介绍如何通过API接口实现1688平台的图片搜索功…

基于A*算法与贝塞尔曲线的路径规划与可视化:从栅格地图到平滑路径生成

引言 在机器人导航、自动驾驶和游戏开发等领域,路径规划是一个核心问题。如何高效地找到从起点到终点的最优路径,并且确保路径的平滑性和安全性,是许多应用场景中的关键挑战。本文将介绍一种结合A算法和贝塞尔曲线的路径规划方法,并通过Pygame实现可视化。我们将从栅格地图…

使用verilog 实现 cordic 算法 ----- 旋转模式

1-设计流程 ● 了解cordic 算法原理&#xff0c;公式&#xff0c;模式&#xff0c;伸缩因子&#xff0c;旋转方向等&#xff0c;推荐以下链接视频了解 cordic 算法。哔哩哔哩-cordic算法原理讲解 ● 用matlab 或者 c 实现一遍算法 ● 在FPGA中用 verilog 实现&#xff0c;注意…

【css】width:100%;padding:20px;造成超出100%宽度的解决办法 - box-sizing的使用方法 - CSS布局

问题 修改效果 解决方法 .xx {width: 100%;padding: 0 20px;box-sizing: border-box; } 默认box-sizing: content-box下&#xff0c; width 内容的宽度 height 内容的高度 宽度和高度的计算值都不包含内容的边框&#xff08;border&#xff09;和内边距&#xff08;padding&…

贪心算法_翻硬币

蓝桥账户中心 依次遍历 不符合条件就反转 题目要干嘛 你就干嘛 #include <bits/stdc.h>#define endl \n using namespace std;int main() {ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); string s; cin >> s;string t; cin >> t;int ret 0;for ( i…

深入HBase——引入

引入 前面我们通过深入HDFS到深入MapReduce &#xff0c;从设计和落地&#xff0c;去深入了解了大数据最底层的基石——存储与计算是如何实现的。 这个专栏则开始来看大数据的三驾马车中最后一个。 通过前面我们对于GFS和MapReduce论文实现的了解&#xff0c;我们知道GFS在数…

2025年02月12日Github流行趋势

项目名称&#xff1a;data-formulator 项目地址url&#xff1a;https://github.com/microsoft/data-formulator 项目语言&#xff1a;TypeScript 历史star数&#xff1a;4427 今日star数&#xff1a;729 项目维护者&#xff1a;danmarshall, Chenglong-MS, apps/dependabot, mi…

【落羽的落羽 数据结构篇】双向链表

文章目录 一、链表的分类二、双向链表1. 结构2. 申请一个新节点3. 尾部插入数据4. 头部插入数据5. 尾部删除数据6. 头部删除数据7. 在指定位置之后插入数据8. 删除指定位置节点9. 销毁链表 一、链表的分类 链表的分类实际上要从这三个方向分析&#xff1a;是否带头、单向还是双…

Golang的并发编程问题解决思路

Golang的并发编程问题解决思路 一、并发编程基础 并发与并行 在计算机领域&#xff0c;“并发”和“并行”经常被混为一谈&#xff0c;但它们有着不同的含义。并发是指一段时间内执行多个任务&#xff0c;而并行是指同时执行多个任务。在 Golang 中&#xff0c;通过 goroutines…

剑指offer第2版:搜索算法(二分/DFS/BFS)

查找本质就是排除的过程&#xff0c;不外乎顺序查找、二分查找、哈希查找、二叉排序树查找、DFS/BFS查找 一、p39-JZ3 找出数组中重复的数字&#xff08;利用特性&#xff09; 数组中重复的数字_牛客题霸_牛客网 方法1&#xff1a;全部排序再进行逐个扫描找重复。 时间复杂…

在 CentOS 上更改 SSH 默认端口以提升服务器安全性

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall ︱vue3-element-admin︱youlai-boot︱vue-uniapp-template &#x1f33a; 仓库主页&#xff1a; GitCode︱ Gitee ︱ Github &#x1f496; 欢迎点赞 &#x1f44d; 收藏 ⭐评论 …

2025年:边缘计算崛起下运维应对新架构挑战

一、引言 随着科技的飞速发展&#xff0c;2025年边缘计算正以前所未有的速度崛起&#xff0c;给运维行业带来了全新的架构挑战。在这个充满机遇与挑战的时代&#xff0c;美信时代公司的美信监控易运维管理软件成为运维领域应对这些挑战的有力武器。 二、边缘计算崛起带来的运维…

怎么理解 Spring Boot 的约定优于配置 ?

在传统的 Spring 开发中&#xff0c;大家可能都有过这样的经历&#xff1a;项目还没开始写几行核心业务代码&#xff0c;就已经在各种配置文件中耗费了大量时间。比如&#xff0c;要配置数据库连接&#xff0c;不仅要在 XML 文件里编写冗长的数据源配置&#xff0c;还要处理事务…

学习总结2.14

深搜将题目分配&#xff0c;如果是两个题目&#xff0c;就可以出现左左&#xff0c;左右&#xff0c;右左&#xff0c;右右四种时间分配&#xff0c;再在其中找最小值&#xff0c;即是两脑共同处理的最小值 #include <stdio.h> int s[4]; int sum0; int brain[25][25]; …

Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档

Electron 客户端心跳定时任务调度库调研文档 - Node.js 任务调度库技术调研文档 本文将对七个流行的定时任务调度库&#xff1a;node-cron、rxjs、bull、node-schedule、agenda、bree、cron。这些库都可以用来处理定时任务&#xff0c;但它们的特点和适用场景有所不同。我们将从…

【学术投稿-第四届智能电网和绿色能源国际学术会议(ICSGGE 2025)】CSS基本选择器详解:掌握基础,轻松布局网页

可线上 官网&#xff1a;www.icsgge.org 时间&#xff1a;2025年2月28-3月2日 目录 前言 一、基本选择器简介 1. 元素选择器&#xff08;Type Selector&#xff09; 基本语法 示例 注意事项 2. 类选择器&#xff08;Class Selector&#xff09; 基本语法 示例 注意…

singleTaskAndroid的Activity启动模式知识点总结

一. 前提知识 1.1. 任务栈知识 二. Activity启动模式的学习 2.1 standard 2.2 singleTop 2.3.singleTask 2.4.singleInstance 引言&#xff1a; Activity作为四大组件之一&#xff0c;也可以说Activity是其中最重要的一个组件&#xff0c;其负责调节APP的视图&#xff…

Vue 入门到实战 十

第10章 Vue Router​​​​​​​ 目录 10.1 什么是路由 10.2 Vue Router的安装 10.2.1 本地独立版本方法 10.2.2 CDN方法 10.2.3 NPM方法 10.2.4 命令行工具&#xff08;Vue CLI&#xff09;方法 10.3 Vue Router的基本用法 10.3.1 跳转与传参 10.3.2 配置路由 10.…

jenkins-获取当前时间戳

一. 简述&#xff1a; 很多场景下&#xff0c;需要获取当前时间戳。 二. 使用方法&#xff1a; 1. 安装&#xff1a; 最简单的&#xff0c; 莫过于直接部署相关插件&#xff1a; Build Timestamp Plugin 2. 配置&#xff1a; 3. 使用&#xff1a; post {success {script…

【Jenkins流水线搭建】

Jenkins流水线搭建 01、SpringBoot项目 - Jenkins基于Jar持续集成搭建文档基于手动方式发布项目基于dockerfile基于jenkins + dockerfile + jenkinsfile +pieline基于jenkins + jar方式的发布01、环境说明01、准备项目02、准备服务器03、安装git04、安装jdk1.805、安装maven依赖…