Android13 WMS窗口层级树

1,认识层级树
可以通过dumpsys activity containers 看到 WMS 层级树的结构

ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)
ROOT type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Display 0 name="Built-in Screen" type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][1440,2960] bounds=[0,0][1440,2960]#2 Leaf:36:36 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 WindowToken{6cc524e type=2024 android.os.BinderProxy@8ffb949} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 888c47c ScreenDecorOverlayBottom type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowToken{4346895 type=2024 android.os.BinderProxy@ad2b04c} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 da08538 ScreenDecorOverlay type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 HideDisplayCutout:32:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#2 OneHanded:34:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:34:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:34:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 FullscreenMagnification:33:33 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:33:33 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 OneHanded:32:32 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:32:32 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowedMagnification:0:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#6 HideDisplayCutout:26:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 OneHanded:26:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#2 FullscreenMagnification:29:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:29:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 Leaf:28:28 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:26:27 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:26:27 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#5 Leaf:24:25 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 WindowToken{914ccc0 type=2024 android.os.BinderProxy@60ae43} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 20f913e pip-dismiss-overlay type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowToken{4af2b8f type=2019 android.os.BinderProxy@d5bc069} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 e66fa25 NavigationBar0 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#4 HideDisplayCutout:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 OneHanded:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#3 OneHanded:17:17 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:17:17 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:17:17 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowToken{2cb42e4 type=2040 android.os.BinderProxy@9c0076} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 bbfae02 NotificationShade type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#2 HideDisplayCutout:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 OneHanded:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 OneHanded:15:15 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:15:15 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:15:15 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowToken{36a0a7c type=2000 android.os.BinderProxy@57ea84e} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 f20fb5a StatusBar type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 HideDisplayCutout:0:14 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 OneHanded:0:14 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 ImePlaceholder:13:14 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 ImeContainer type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowToken{18b2fcb type=2011 android.os.Binder@f3da9a} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 3a9ce61 InputMethod type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 FullscreenMagnification:0:12 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#2 Leaf:3:12 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WindowToken{fc9ff07 type=2038 android.os.BinderProxy@d280149} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 d5c8415 ShellDropTarget type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 DefaultTaskDisplayArea type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#2 Task=1 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Task=24 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 ActivityRecord{7246b16 u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t24} type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 bd08f5d com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 Task=3 type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Task=4 type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#1 Task=6 type=undefined mode=multi-window override-mode=multi-window requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Task=5 type=undefined mode=multi-window override-mode=multi-window requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 Leaf:0:1 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 WallpaperWindowToken{a0c14b1 token=android.os.Binder@c234b58} type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]#0 b9a90a8 com.android.systemui.ImageWallpaper type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1440,2960]

可以看出,层级机构树一共有37层,层级越高,越接近我们的"眼睛",以上父子关系,做成图表格式,可以看的更直观,如下:

在这里插入图片描述
2,层级结构树的构建过程
SystemServer启动时,调用startOtherServices方法

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {//省略t.traceBegin("SetWindowManagerService");mActivityManagerService.setWindowManager(wm);t.traceEnd();//省略
}

AMS.setWindowManager

 public void setWindowManager(WindowManagerService wm) {synchronized (this) {mWindowManager = wm;mWmInternal = LocalServices.getService(WindowManagerInternal.class);mActivityTaskManager.setWindowManager(wm);}}

ATMS.setWindowManager

public void setWindowManager(WindowManagerService wm) {synchronized (mGlobalLock) {//省略mRootWindowContainer.setWindowManager(wm);//省略}}

RootWindowContainer.setWindowManager

void setWindowManager(WindowManagerService wm) {//省略final Display[] displays = mDisplayManager.getDisplays();//得到系统有几个显示设备for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {//遍历displayfinal Display display = displays[displayNdx];final DisplayContent displayContent = new DisplayContent(display, this);//创建DisplayContentaddChild(displayContent, POSITION_BOTTOM);//将DisplayContent挂在root下if (displayContent.mDisplayId == DEFAULT_DISPLAY) {mDefaultDisplay = displayContent;}}//省略}

对于每个显示设备,系统都会创建一个DisplayContent对象,并将DisplayContent对象挂在root下。接着来看一下DisplayContent的创建

DisplayContent(Display display, RootWindowContainer root) {//省略configureSurfaces(pendingTransaction);//省略
}

configureSurfaces

 private void configureSurfaces(Transaction transaction) {final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession).setOpaque(true).setContainerLayer().setCallsite("DisplayContent");mSurfaceControl = b.setName(getName()).setContainerLayer().build();if (mDisplayAreaPolicy == null) {// Setup the policy and build the display area hierarchy.// Build the hierarchy only after creating the surface so it is reparented correctlymDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(mWmService, this /* content */, this /* root */,mImeWindowsContainer);}//省略

getDisplayAreaPolicyProvider得到的是DefaultProvider对象,然后调用其instantiate方法。源码路径:frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicy.java

static final class DefaultProvider implements DisplayAreaPolicy.Provider {@Overridepublic DisplayAreaPolicy instantiate(WindowManagerService wmService,DisplayContent content, RootDisplayArea root,DisplayArea.Tokens imeContainer) {final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,"DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);//创建DefaultTaskDisplayAreafinal List<TaskDisplayArea> tdaList = new ArrayList<>();tdaList.add(defaultTaskDisplayArea);// Define the features that will be supported under the root of the whole logical// display. The policy will build the DisplayArea hierarchy based on this.final HierarchyBuilder rootHierarchy = new HierarchyBuilder(root);// Set the essential containers (even if the display doesn't support IME).rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);//1if (content.isTrusted()) {// Only trusted display can have system decorations.configureTrustedHierarchyBuilder(rootHierarchy, wmService, content);//2}// Instantiate the policy with the hierarchy defined above. This will create and attach// all the necessary DisplayAreas to the root.return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);//3}

首先创建HierarchyBuilder对象,注释1处将imeContainer和tdaList(tdaList此时只有一个元素就是DefaultTaskDisplayArea)分别保存在HierarchyBuilder对象中的mImeContainer和mTaskDisplayAreas中。注释2处创建Feature并设置Feature的层级。注释3处开始构建层级树

2.1,创建Feature
configureTrustedHierarchyBuilder

//frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
private void configureTrustedHierarchyBuilder(HierarchyBuilder rootHierarchy,WindowManagerService wmService, DisplayContent content) {// WindowedMagnification should be on the top so that there is only one surface// to be magnified.rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification",FEATURE_WINDOWED_MAGNIFICATION).upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY).except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)// Make the DA dimmable so that the magnify window also mirrors the dim layer..setNewDisplayAreaSupplier(DisplayArea.Dimmable::new).build());if (content.isDefaultDisplay) {// Only default display can have cutout.// See LocalDisplayAdapter.LocalDisplayDevice#getDisplayDeviceInfoLocked.rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "HideDisplayCutout",FEATURE_HIDE_DISPLAY_CUTOUT).all().except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL, TYPE_STATUS_BAR,TYPE_NOTIFICATION_SHADE).build()).addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded",FEATURE_ONE_HANDED).all().except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL,TYPE_SECURE_SYSTEM_OVERLAY).build());}rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "FullscreenMagnification",FEATURE_FULLSCREEN_MAGNIFICATION).all().except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD,TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY,TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL).build()).addFeature(new Feature.Builder(wmService.mPolicy, "ImePlaceholder",FEATURE_IME_PLACEHOLDER).and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG).build());}}

可以看出,这里创建了几个Feature,以及它们对应的层级是:

  1. WindowedMagnification:0~31
  2. HideDisplayCutout: 0~ 14 16 18~ 23 26~35
  3. OneHanded:0~ 23 26~ 32 34~35
  4. FullscreenMagnification:0~ 12 15~ 23 26~ 27 29~ 31 33~35
  5. ImePlaceholder:13 14
    至于层级是怎么得出来的,具体查看Feature.Builder的 all,except等等方法。Feature以及对应的层级设置好之后,接下来就是要开始构建层级树了。

2.2, 层级树的构建
源码路径:frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java

Result build(WindowManagerService wmService) {validate();// Attach DA group roots to screen hierarchy before adding windows to group hierarchies.mRootHierarchyBuilder.build(mDisplayAreaGroupHierarchyBuilders);//省略}

mRootHierarchyBuilder就是之前创建的HierarchyBuilder对象,调用其build方法。构建层级树的核心就是该方法,来分步分析它

2.2.1 挂载 Feature

private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;// 37final DisplayArea.Tokens[] displayAreaForLayer =new DisplayArea.Tokens[maxWindowLayerCount];final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas =new ArrayMap<>(mFeatures.size());//前面创建了5个Feature,所以size为5for (int i = 0; i < mFeatures.size(); i++) {featureAreas.put(mFeatures.get(i), new ArrayList<>());}PendingArea[] areaForLayer = new PendingArea[maxWindowLayerCount];final PendingArea root = new PendingArea(null, 0, null);Arrays.fill(areaForLayer, root);//此时里面的每个元素都是root 0,0// Create DisplayAreas to cover all defined features.final int size = mFeatures.size();for (int i = 0; i < size; i++) {final Feature feature = mFeatures.get(i);PendingArea featureArea = null;for (int layer = 0; layer < maxWindowLayerCount; layer++) {if (feature.mWindowLayers[layer]) {if (featureArea == null || featureArea.mParent != areaForLayer[layer]) {// No suitable DisplayArea:// Create a new one under the previous area (as parent) for this layer.featureArea = new PendingArea(feature, layer, areaForLayer[layer]);areaForLayer[layer].mChildren.add(featureArea);}areaForLayer[layer] = featureArea;} else {featureArea = null;}}}

创建一个临时的层级结构树PendingArea(后面还需要转换成真正的层级树的),对于Feature,其构造结果如下
在这里插入图片描述
2.2.2,挂载leaf叶子结点

private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {//省略// Create Tokens as leaf for every layer.PendingArea leafArea = null;int leafType = LEAF_TYPE_TOKENS;for (int layer = 0; layer < maxWindowLayerCount; layer++) {int type = typeOfLayer(policy, layer);// Check whether we can reuse the same Tokens with the previous layer. This happens// if the previous layer is the same type as the current layer AND there is no// feature that applies to only one of them.if (leafArea == null || leafArea.mParent != areaForLayer[layer]|| type != leafType) {// Create a new Tokens for this layer.leafArea = new PendingArea(null /* feature */, layer, areaForLayer[layer]);areaForLayer[layer].mChildren.add(leafArea);leafType = type;if (leafType == LEAF_TYPE_TASK_CONTAINERS) {// We use the passed in TaskDisplayAreas for task container type of layer.// Skip creating Tokens even if there is no TDA.addTaskDisplayAreasToApplicationLayer(areaForLayer[layer]);addDisplayAreaGroupsToApplicationLayer(areaForLayer[layer],displayAreaGroupHierarchyBuilders);leafArea.mSkipTokens = true;} else if (leafType == LEAF_TYPE_IME_CONTAINERS) {// We use the passed in ImeContainer for ime container type of layer.// Skip creating Tokens even if there is no ime container.leafArea.mExisting = mImeContainer;leafArea.mSkipTokens = true;}}leafArea.mMaxLayer = layer;}
}

首先也是创建临时的叶子PendingArea,leafType默认为LEAF_TYPE_TOKENS,在typeOfLayer方法中,对于IME和Application 有处理,将其leafType设为LEAF_TYPE_TASK_CONTAINERS和LEAF_TYPE_IME_CONTAINERS。注意对于这两种类型,有特殊的处理,mSkipTokens设置为了true,后续将临时的结构树转成真正的层级树的时候有用。
经过这一步,此时结构树的构造结果如下
在这里插入图片描述
2.2.3 将临时的结构树转成真正的结构树

在build方法的最后,调用instantiateChildren方法,进行结构树的转换

void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));for (int i = 0; i < mChildren.size(); i++) {final PendingArea child = mChildren.get(i);final DisplayArea area = child.createArea(parent, areaForLayer);//转换if (area == null) {// TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can// be null.continue;}parent.addChild(area, WindowContainer.POSITION_TOP);if (child.mFeature != null) {areas.get(child.mFeature).add(area);}child.instantiateChildren(area, areaForLayer, level + 1, areas);//迭代的过程}}

在createArea中,对于IME和Application Layer是有特殊处理的,删掉上面对应结点下的leaf叶子,最终转换好的结构树如下
在这里插入图片描述

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

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

相关文章

中国能源统计年鉴(1986-2023年)

数据年份&#xff1a;1986-2023年&#xff0c;无1987、1988、1990三年&#xff0c;1991-2023年齐 数据格式&#xff1a;pdf、excel 数据内容&#xff1a;《中国能源统计年鉴》是一部反映中国能源建设、生产、消费、供需平衡的权威性资料书。 共分为7个篇章&#xff1a;1.综合&a…

论文学习_多平台二进制代码分类与相似性检测技术研究

0. 摘要 研究背景:二进制代码分类与相似性检测是恶意代码家族分析、软件代码溯源的基础,对保障网络空间安全具有重要作用。 现存问题:在多种平台下,二进制代码包括 PE、ELF、DEX 等形态的文件格式,并设计 X86、ARM、MIPS、PPC 等指令架构。而在同一平台下,同一份软件代…

excel按模板文件导出多个文件并压缩为ZIP格式返回前端

思路&#xff1a;先准备好模板文件和与之对应的实体类&#xff0c;数据库数据等&#xff0c;还是之前思路&#xff0c;根据查出的数据&#xff0c;填充模板文件&#xff0c;生成一个临时文件&#xff0c;最后将这些个临时文件打包为zip返回前端&#xff0c;并将多个临时文件删除…

51-52Windows密码安全性测试与Windows提权

目录 Windows密码安全性测试 一、本地管理员密码如何直接提取 1、直接通过mimikatz读取管理员密码 2、使用laZagne工具读取管理员密码 二、利用Hash远程登录系统 window提权 三、远程webshell执行命令解决 不能执行原因&#xff1a; 解决方法&#xff1a;单独上传cmd.e…

计算机专业如何自学?经验交流分享

想自学计算机的小伙伴一定要学会自己找信息&#xff0c;然后制定自己的学习计划去好好执行下去&#xff0c;要不然永远都是停留在想的阶段&#xff0c;找了一大堆资料&#xff0c;却永远不真正开始学习&#xff0c;这样的话&#xff0c;估计给你再多的时间也没法入门&#xff0…

MPI 介绍MPI 全名叫 Message Passing Interface,

一、MPI 介绍 MPI 全名叫 Message Passing Interface&#xff0c;即信息传递接口&#xff0c;作用是可以通过 MPI 可以在不同进程间传递消息&#xff0c;从而可以并行地处理任务&#xff0c;即进行并行计算。需要注意的是&#xff0c;尽管我们偶尔会说使用 MPI 编写了某某可执…

linux系统cpu飙高如何排查

1.通过top命令查看cpu占比较高的进程ID 2.通过top -H -p <进程ID>命令查看该进程中具体线程&#xff0c;可以看到第一个线程 4311 占用了88.2%的cpu 3.通过 printf "%x\n" <线程ID> 把10进制的线程id转为16进制 4.通过jstack <进程ID> | grep &…

【大疆pocket3】到手后5个必改初始设置关键点(下)

【大疆pocket3】到手后5个必改初始设置关键点&#xff08;下&#xff09; 一&#xff0c;简介二&#xff0c;必改关键点2.1 数字变焦2.2 慢动作拍摄2.3 神奇的小摇杆2.4 云台模式使用方法&#xff08;默认增稳模式和俯仰角锁定的差异化以及使用场景&#xff09;2.5 云台转向速度…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《基于已知电网场景分段拟合智能体智能评估与自主进化方法 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

为什么 JakeWharton 建议:App 只要用到一个 Activity ?

我们来看看这条回答都提到了哪些内容&#xff0c;对 Activity 和 Fragment 之间的爱恨情仇有何独到的见解&#xff0c;凭什么能得到 JakeWharton 本尊的青睐有加。 因为 Activity 是一个程序入口。你可以将其视为 app 的一个 main 函数。站在用户的立场上&#xff0c;通常你进入…

cesium 包络线

cesium 包络线 以下为源码直接复制可用 1、实现思路 通过turf.js中union方法来计算包络线官方地址:https://turfjs.fenxianglu.cn/ 闪烁线请查看cesium轨迹线(闪烁轨迹线) 2、示例代码 <!DOCTYPE html> <html lang="en"&g

带你学习Mybatis之mybatis的sql节点

mybatis的sql节点 mybatis的mapper映射文件中的sql节点在初始化时会被解析成MappedStatement对象&#xff0c;其中sql语句会被解析为SqlSource对象&#xff0c;sql语句中定义的动态sql节点、文本节点等则由SqlNode接口的相应实现类表示 SqlSource public interface SqlSource {…

Vue3中使用el-table遇到的问题

我在使用element-plus中el-table组件的时候&#xff0c;对于某一<el-table-column>标签内的内容设置show-overflow-tooltip属性&#xff0c;但这里溢出展示的tooltip的默认样式是无法像el-tooltip标签那样&#xff0c;直接可以修改的。默认的样式是这样&#xff1a; 因此…

1.树莓派4b+ubuntu18.04(ros版本melodic)+arduino mega自制两轮差速小车,实现建图导航功能

第一篇先介绍材料准备、环境配置和ros的安装 1.材料准备 1.树莓派4b&#xff0c;8g版本 2.arduino mega 3.MG310编码电机*2 4.雷达ydlidar X3 5.Tb6612电机驱动板 6.12v电池 7.ubuntu18.04ros melodic版本 2.环境配置 树莓派安装ubuntu18.04版本 ubuntu18.04版本的镜像可以…

Java中如何正确使用异常处理?

Java中如何正确使用异常处理&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在Java编程中&#xff0c;异常处理是确保程序稳定性和可靠性的重要部分…

【java】写一个发送邮箱的样例

【java】写一个发送邮箱的样例package com.ai157.aigc.controller.methods; import javax.mail.*; import javax.mail.internet.*; import java.util.Date; import java.util.Properties;public class SendEmail {/* public static void main(String[] args) {toMsg("3…

刷题——旋转数组的最小数字

旋转数组的最小数字_牛客题霸_牛客网 描述 有一个长度为 n 的非降序数组&#xff0c;比如[1,2,3,4,5]&#xff0c;将它进行旋转&#xff0c;即把一个数组最开始的若干个元素搬到数组的末尾&#xff0c;变成一个旋转数组&#xff0c;比如变成了[3,4,5,1,2]&#xff0c;或者[4,…

django DRF增删改查

本文在django所有的增删改查样例使用的DRF框架序列化操作&#xff0c;并非是简单的orm操作。 目录 ORM介绍数据库设计原则DRF增删改操作高级查询原生sql处理 ORM介绍 Django ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;是 Django 框架的一…

安装vue时候发现npm淘宝镜像不能使用,报出:npm.taobao.org和registry.npm.taobao.or

2024.3.12 安装vue时候发现npm淘宝镜像不能使用&#xff0c;需要重新更换源&#xff0c;简单来说就是更换镜像 使用 npm config get registry 查看当前的镜像&#xff1b; npm config get registry 使用npm config set registry http://mirrors.cloud.tencent.com/npm/ &…

食品预包装:舌尖安全的第一道防线

在当今快节奏的生活中&#xff0c;食品预包装不仅是保护食品的屏障&#xff0c;更是传递品质与美味的使者。 预包装首先展现出的是其保鲜的魔力。它宛如一层坚固的护盾&#xff0c;有效地阻隔外界因素对食品的侵蚀&#xff0c;让食品的新鲜度和口感得以长久保存。无论是酥脆的点…