Android14 - WindowManagerService之客户端Activity布局

news2024/10/8 11:42:52

Android14 - WindowManagerService之客户端Activity布局

主要角色

WMS作为一个服务端,有多种客户端与其交互的场景。我们以常见的Activity为例

ActivityActivityThread构建一个Activity调用attach方法attach构建一个PhoneWindow

PhoneWindow一个Activity对应一个PhoneWindow每个PhoneWindow持有一个WindowManagerImpl对象

WindowManagerImpl服务端WMS客户端代理WindowManagerImpl持有WindowManagerGlobal

WindowManagerGlobal进程单例WindowManagerGlobal不仅持有WMS服务端的WindowManagerService、WindowSession的引用并且集合所有ViewRootImplDecorView

ViewRootImpl每个Activity对应一个ViewRootImp对象ViewRootImp作为客户端与WMS桥梁。从客户端到服务端的角度,ViewRootImp持有WindowSession对象服务端Session引用,一个Session对应一个window服务端客户端角度ViewRootImp有一个子类Wbinder通信服务端W对象引用WMS持有用来服务端客户端通信另外ViewRootImp持有DecorView对象逻辑上ViewRootImplView本身并不是一个View只是实现ViewParent接口DecorViewViewRootImp子类(见setView()方法中的view.assignParent(this)

DecorView每个Activity对应一个DecorViewDecorView真正顶层View,是最外层的view其inflate PhoneWidow过来layout,将其addView作为自己的第0个类DecorView维护一个窗口基本结构包括内容区域titlebar区域

窗口的构建过程

窗口结构大致如下

其过程参考上图,在PhoneWindow初始化过程调用generateLayout(DecorView decor)方法其中一个window整体画面进行初始化

protected ViewGroup generateLayout(DecorView decor) {
	// Apply data from current theme.

	// Style来自于Theme xml文件
	TypedArray a = getWindowStyle();

	mIsFloating = a.getBoolean(R.styleable.Window_windowIsFloating, false);
	int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR)
			& (~getForcedWindowFlags());
	if (mIsFloating) {
		setLayout(WRAP_CONTENT, WRAP_CONTENT);
		setFlags(0, flagsToUpdate);
	} else {
		setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
		getAttributes().setFitInsetsSides(0);
		getAttributes().setFitInsetsTypes(0);
	}

	if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
		requestFeature(FEATURE_NO_TITLE);
	} else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {
		// Don't allow an action bar if there is no title.
		requestFeature(FEATURE_ACTION_BAR);
	}

	if (a.getBoolean(R.styleable.Window_windowActionBarOverlay, false)) {
		requestFeature(FEATURE_ACTION_BAR_OVERLAY);
	}

	if (a.getBoolean(R.styleable.Window_windowActionModeOverlay, false)) {
		requestFeature(FEATURE_ACTION_MODE_OVERLAY);
	}

	if (a.getBoolean(R.styleable.Window_windowFullscreen, false)) {
		setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN & (~getForcedWindowFlags()));
	}

	if (a.getBoolean(R.styleable.Window_windowTranslucentStatus,
			false)) {
		setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS
				& (~getForcedWindowFlags()));
	}

	if (a.getBoolean(R.styleable.Window_windowTranslucentNavigation,
			false)) {
		setFlags(FLAG_TRANSLUCENT_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION
				& (~getForcedWindowFlags()));
	}

	if (a.getBoolean(R.styleable.Window_windowShowWallpaper, false)) {
		setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
	}

	if (a.getBoolean(R.styleable.Window_windowEnableSplitTouch,
			getContext().getApplicationInfo().targetSdkVersion
					>= android.os.Build.VERSION_CODES.HONEYCOMB)) {
		setFlags(FLAG_SPLIT_TOUCH, FLAG_SPLIT_TOUCH&(~getForcedWindowFlags()));
	}

	a.getValue(R.styleable.Window_windowMinWidthMajor, mMinWidthMajor);
	a.getValue(R.styleable.Window_windowMinWidthMinor, mMinWidthMinor);
	if (DEBUG) Log.d(TAG, "Min width minor: " + mMinWidthMinor.coerceToString()
			+ ", major: " + mMinWidthMajor.coerceToString());
	if (a.hasValue(R.styleable.Window_windowFixedWidthMajor)) {
		if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
		a.getValue(R.styleable.Window_windowFixedWidthMajor,
				mFixedWidthMajor);
	}
	if (a.hasValue(R.styleable.Window_windowFixedWidthMinor)) {
		if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
		a.getValue(R.styleable.Window_windowFixedWidthMinor,
				mFixedWidthMinor);
	}
	if (a.hasValue(R.styleable.Window_windowFixedHeightMajor)) {
		if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
		a.getValue(R.styleable.Window_windowFixedHeightMajor,
				mFixedHeightMajor);
	}
	if (a.hasValue(R.styleable.Window_windowFixedHeightMinor)) {
		if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
		a.getValue(R.styleable.Window_windowFixedHeightMinor,
				mFixedHeightMinor);
	}
	if (a.getBoolean(R.styleable.Window_windowContentTransitions, false)) {
		requestFeature(FEATURE_CONTENT_TRANSITIONS);
	}
	if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) {
		requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
	}

	mIsTranslucent = a.getBoolean(R.styleable.Window_windowIsTranslucent, false);

	final Context context = getContext();
	final int targetSdk = context.getApplicationInfo().targetSdkVersion;
	final boolean targetPreL = targetSdk < android.os.Build.VERSION_CODES.LOLLIPOP;
	final boolean targetPreQ = targetSdk < Build.VERSION_CODES.Q;

	if (!mForcedStatusBarColor) {
		mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, Color.BLACK);
	}
	if (!mForcedNavigationBarColor) {
		final int navBarCompatibleColor = context.getColor(R.color.navigation_bar_compatible);
		final int navBarDefaultColor = context.getColor(R.color.navigation_bar_default);
		final int navBarColor = a.getColor(R.styleable.Window_navigationBarColor,
				navBarDefaultColor);

		mNavigationBarColor =
				navBarColor == navBarDefaultColor
						&& !context.getResources().getBoolean(
								R.bool.config_navBarDefaultTransparent)
				? navBarCompatibleColor
				: navBarColor;

		mNavigationBarDividerColor = a.getColor(R.styleable.Window_navigationBarDividerColor,
				Color.TRANSPARENT);
	}
	if (!targetPreQ) {
		mEnsureStatusBarContrastWhenTransparent = a.getBoolean(
				R.styleable.Window_enforceStatusBarContrast, false);
		mEnsureNavigationBarContrastWhenTransparent = a.getBoolean(
				R.styleable.Window_enforceNavigationBarContrast, true);
	}

	WindowManager.LayoutParams params = getAttributes();

	// Non-floating windows on high end devices must put up decor beneath the system bars and
	// therefore must know about visibility changes of those.
	if (!mIsFloating) {
		if (!targetPreL && a.getBoolean(
				R.styleable.Window_windowDrawsSystemBarBackgrounds,
				false)) {
			setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
					FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
		}
		if (mDecor.mForceWindowDrawsBarBackgrounds) {
			params.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
		}
		params.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
	}
	if (a.getBoolean(
			R.styleable.Window_windowNoMoveAnimation,
			false)) {
		params.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
	}
	final int sysUiVis = decor.getSystemUiVisibility();
	final int statusLightFlag = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
	final int statusFlag = a.getBoolean(R.styleable.Window_windowLightStatusBar, false)
			? statusLightFlag : 0;
	final int navLightFlag = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
	final int navFlag = a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)
			? navLightFlag : 0;
	decor.setSystemUiVisibility(
			(sysUiVis & ~(statusLightFlag | navLightFlag)) | (statusFlag | navFlag));
	if (a.hasValue(R.styleable.Window_windowLayoutInDisplayCutoutMode)) {
		int mode = a.getInt(R.styleable.Window_windowLayoutInDisplayCutoutMode, -1);
		if (mode < LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
				|| mode > LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
			throw new UnsupportedOperationException("Unknown windowLayoutInDisplayCutoutMode: "
					+ a.getString(R.styleable.Window_windowLayoutInDisplayCutoutMode));
		}
		params.layoutInDisplayCutoutMode = mode;
	}

	if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
			>= android.os.Build.VERSION_CODES.HONEYCOMB) {
		if (a.getBoolean(
				R.styleable.Window_windowCloseOnTouchOutside,
				false)) {
			setCloseOnTouchOutsideIfNotSet(true);
		}
	}

	if (!hasSoftInputMode()) {
		params.softInputMode = a.getInt(
				R.styleable.Window_windowSoftInputMode,
				params.softInputMode);
	}

	if (a.getBoolean(R.styleable.Window_backgroundDimEnabled,
			mIsFloating)) {
		/* All dialogs should have the window dimmed */
		if ((getForcedWindowFlags()&WindowManager.LayoutParams.FLAG_DIM_BEHIND) == 0) {
			params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
		}
		if (!haveDimAmount()) {
			params.dimAmount = a.getFloat(
					android.R.styleable.Window_backgroundDimAmount, 0.5f);
		}
	}

	if (a.getBoolean(R.styleable.Window_windowBlurBehindEnabled, false)) {
		if ((getForcedWindowFlags() & WindowManager.LayoutParams.FLAG_BLUR_BEHIND) == 0) {
			params.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
		}

		params.setBlurBehindRadius(a.getDimensionPixelSize(
				android.R.styleable.Window_windowBlurBehindRadius, 0));
	}

	setBackgroundBlurRadius(a.getDimensionPixelSize(
			R.styleable.Window_windowBackgroundBlurRadius, 0));


	if (params.windowAnimations == 0) {
		params.windowAnimations = a.getResourceId(
				R.styleable.Window_windowAnimationStyle, 0);
	}

	// The rest are only done if this window is not embedded; otherwise,
	// the values are inherited from our container.
	if (getContainer() == null) {
		if (mBackgroundDrawable == null) {

			if (mFrameResource == 0) {
				mFrameResource = a.getResourceId(R.styleable.Window_windowFrame, 0);
			}

			if (a.hasValue(R.styleable.Window_windowBackground)) {
				mBackgroundDrawable = a.getDrawable(R.styleable.Window_windowBackground);
			}
		}
		if (a.hasValue(R.styleable.Window_windowBackgroundFallback)) {
			mBackgroundFallbackDrawable =
					a.getDrawable(R.styleable.Window_windowBackgroundFallback);
		}
		if (mLoadElevation) {
			mElevation = a.getDimension(R.styleable.Window_windowElevation, 0);
		}
		mClipToOutline = a.getBoolean(R.styleable.Window_windowClipToOutline, false);
		mTextColor = a.getColor(R.styleable.Window_textColor, Color.TRANSPARENT);
	}

	// Inflate the window decor.
    // 根据Feature的设置,选择不同的layout xml。具体的resource来源于platform/frameworks/base/core/res/res,根据不同平台选择具体的资源文件。
	// 如果什么都没有设置,最后默认的会选择R.layout.screen_simple;
	int layoutResource;
	int features = getLocalFeatures();
	// System.out.println("Features: 0x" + Integer.toHexString(features));
	if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
		if (mIsFloating) {
			TypedValue res = new TypedValue();
			getContext().getTheme().resolveAttribute(
					R.attr.dialogTitleIconsDecorLayout, res, true);
			layoutResource = res.resourceId;
		} else {
			layoutResource = R.layout.screen_title_icons;
		}
		// XXX Remove this once action bar supports these features.
		removeFeature(FEATURE_ACTION_BAR);
		// System.out.println("Title Icons!");
	} else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0
			&& (features & (1 << FEATURE_ACTION_BAR)) == 0) {
		// Special case for a window with only a progress bar (and title).
		// XXX Need to have a no-title version of embedded windows.
		layoutResource = R.layout.screen_progress;
		// System.out.println("Progress!");
	} else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {
		// Special case for a window with a custom title.
		// If the window is floating, we need a dialog layout
		if (mIsFloating) {
			TypedValue res = new TypedValue();
			getContext().getTheme().resolveAttribute(
					R.attr.dialogCustomTitleDecorLayout, res, true);
			layoutResource = res.resourceId;
		} else {
			layoutResource = R.layout.screen_custom_title;
		}
		// XXX Remove this once action bar supports these features.
		removeFeature(FEATURE_ACTION_BAR);
	} else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {
		// If no other features and not embedded, only need a title.
		// If the window is floating, we need a dialog layout
		if (mIsFloating) {
			TypedValue res = new TypedValue();
			getContext().getTheme().resolveAttribute(
					R.attr.dialogTitleDecorLayout, res, true);
			layoutResource = res.resourceId;
		} else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
			layoutResource = a.getResourceId(
					R.styleable.Window_windowActionBarFullscreenDecorLayout,
					R.layout.screen_action_bar);
		} else {
			layoutResource = R.layout.screen_title;
		}
		// System.out.println("Title!");
	} else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
		layoutResource = R.layout.screen_simple_overlay_action_mode;
	} else {
		// Embedded, so no decoration is needed.
		layoutResource = R.layout.screen_simple;
		// System.out.println("Simple!");
	}

	mDecor.startChanging();
	// 将最终的layoutResource传给DecorView,在DecorView里面去inflate
	mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);

	ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
	if (contentParent == null) {
		throw new RuntimeException("Window couldn't find content container view");
	}

	if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) {
		ProgressBar progress = getCircularProgressBar(false);
		if (progress != null) {
			progress.setIndeterminate(true);
		}
	}

	// Remaining setup -- of background and title -- that only applies
	// to top-level windows.
	if (getContainer() == null) {
		mDecor.setWindowBackground(mBackgroundDrawable);

		final Drawable frame;
		if (mFrameResource != 0) {
			frame = getContext().getDrawable(mFrameResource);
		} else {
			frame = null;
		}
		mDecor.setWindowFrame(frame);

		mDecor.setElevation(mElevation);
		mDecor.setClipToOutline(mClipToOutline);

		if (mTitle != null) {
			setTitle(mTitle);
		}

		if (mTitleColor == 0) {
			mTitleColor = mTextColor;
		}
		setTitleColor(mTitleColor);
	}

	mDecor.finishChanging();

	return contentParent;
}

方法做了几件事

1. 获取主题属性TypedArray a = getWindowStyle();

getWindowStyle最终调用

platform/frameworks/base/core/java/android/content/Context.java

@NonNull
public final TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) {
    return getTheme().obtainStyledAttributes(attrs);
}

Theme获取根据不同平台、版本返回不同的文件:

platform/frameworks/base/core/java/android/content/res/Resources.java

@UnsupportedAppUsage
public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
	return selectSystemTheme(curTheme, targetSdkVersion,
			com.android.internal.R.style.Theme,
			com.android.internal.R.style.Theme_Holo,
			com.android.internal.R.style.Theme_DeviceDefault,
			com.android.internal.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}

/** @hide */
public static int selectSystemTheme(int curTheme, int targetSdkVersion, int orig, int holo,
		int dark, int deviceDefault) {
	if (curTheme != ID_NULL) {
		return curTheme;
	}
	if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
		return orig;
	}
	if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
		return holo;
	}
	if (targetSdkVersion < Build.VERSION_CODES.N) {
		return dark;
	}
	return deviceDefault;
}

对应platform/frameworks/base/core/res/res/values/themes.xmlplatform/frameworks/base/core/res/res/values/themes_holo.xml、platform/frameworks/base/core/res/res/values/themes_device_defaults.xml等这些主题文件

2. 根据theme配置设置featureflags背景

3. 根据设置后的feature选择一个layout文件layoutResourcelayoutResource传给DecorView进行窗口View构建。

一般layout分为上面的titlebar区域下面content区域titlebar部分区域不是固定每个layout可能不同布局content一般固定就是大部分layout一个id为contentlayout

默认platform/frameworks/base/core/res/res/layout/screen_simple.xml文件为例

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:orientation="vertical">
    <ViewStub android:id="@+id/action_mode_bar_stub"
              android:inflatedId="@+id/action_mode_bar"
              android:layout="@layout/action_mode_bar"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="?attr/actionBarTheme" />
    <FrameLayout
         android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:foregroundInsidePadding="false"
         android:foregroundGravity="fill_horizontal|top"
         android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>

action_mode_bar_stub是title部分

@android:id/content主内容区域。对应PhoneWindowmContentParent成员

整个布局对应DecorViewmContentRoot变量,在mContentRoot构建后,也被add到DecorView的第0个Child。具体

platform/frameworks/base/core/java/com/android/internal/policy/DecorView.java

void onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
	if (mBackdropFrameRenderer != null) {
		loadBackgroundDrawablesIfNeeded();
		mBackdropFrameRenderer.onResourcesLoaded(
				this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable,
				mUserCaptionBackgroundDrawable, getCurrentColor(mStatusColorViewState),
				getCurrentColor(mNavigationColorViewState));
	}

	mDecorCaptionView = createDecorCaptionView(inflater);
	final View root = inflater.inflate(layoutResource, null);
	if (mDecorCaptionView != null) {
		if (mDecorCaptionView.getParent() == null) {
			addView(mDecorCaptionView,
					new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
		}
		mDecorCaptionView.addView(root,
				new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
	} else {

		// Put it below the color views.
		addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
	}
	mContentRoot = (ViewGroup) root;
	initializeElevation();
}

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

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

相关文章

FPGA Quartus IP核 打开使用

两种Quartus版本下的IP核&#xff0c;从使用者的角度来看仅仅是配置界面不同&#xff0c;在参数设置和使用方法上基本一致。本文以“MegaWizard Plug-In Manager”中的FIR Compiler IP核使用为例。 Quartus的FIR IP核属于收费IP&#xff0c;如果是个人学习使用需要对IP核单独破…

OpenStack 常见模块详解

目录 一、OpenStack 架构 二、控制台 Dashboard 三、身份认证服务 Keystone 1&#xff09;用户&#xff08;user&#xff09; 2&#xff09;项目&#xff08;project&#xff09; 3&#xff09;角色&#xff08;role&#xff09; 4&#xff09;服务&#xff08;serv…

Linux内核驱动开发-字符设备驱动框架

1前置条件 &#xff08;1&#xff09;【linux】内核编译结束 &#xff08;2&#xff09;【linux】目录配置跳转文件&#xff1a;补充&#xff1a;配置的跳转文件只能在【linux】目录下使用&#xff0c;子目录无法使用2驱动框架 2.1编写驱动程序 #include <linux/init.h&g…

ConcurrentHashMap 源码分析(二)

一、序言 本文和大家探讨一下 ConcurrentHashMap#get() 方法的源码。 二、源码概览 public V get(Object key) {// 定义变量Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;// 计算键的哈希值int h spread(key.hashCode());// 检查哈希表是否为空&#xff…

前端三大件速成 02 CSS(1)CSS是什么、CSS的四种引入方式、CSS的选择器和优先级、继承

文章目录 一、CSS是什么二、CSS的四种引入方式1、行内式2、嵌入式3、链接式&#xff08;推荐&#xff09;4、导入式 三、CSS的选择器1、基本选择器2、组合选择器3、属性选择器4、伪类 四、选择器的优先级1、选择器的权值2、附加说明 五、继承 一、CSS是什么 CSS为层叠样式表&a…

伪分布Hadoop下安装Hive

一、下载并安装Mysql &#xff08;1&#xff09;下载mysql安装包&#xff08;mysql-8.0.26-1.el7.x86_64.rpm-bundle.tar&#xff09; 下载官网&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/ &…

在centos系统中使用boost库

打开MobaXterm软件 下载 boost_1_85_0.tar.gz tar -zxvf boost_1_85_0.tar.gz解压缩成boost_1_85_0文件夹 双击arrayDemo.cpp 在里面可以编写代码 arrayDemo.cpp #include <boost/timer/timer.hpp> #include <boost/array.hpp> #include <cmath> #inc…

Linux 系统systemd(pid=1)占用80端口导致web程序无法启动

背景 linux系统内安装了例如nginx的网站程序&#xff0c;但是无法正常启动&#xff0c;netstat 查看下 80端口被 systemd 占用。 处理方法 注意务必组好快照备份后再操作。 做好备份后将/usr/lib/systemd/system 内http相关的配置文件重命名后重启主机恢复正常。 重启后正常 sy…

51、图论-岛屿数量

思路&#xff1a; 该问题要求在一个由 1&#xff08;表示陆地&#xff09;和 0&#xff08;表示水&#xff09;组成的二维网格中&#xff0c;计算岛屿的数量。岛屿被水包围&#xff0c;并且通过水平或垂直连接相邻的陆地可以形成。这个问题的核心是识别并计数网格中相连的陆地…

网盘——文件操作之界面设计

关于网盘实现部分&#xff0c;文件操作包含三个部分&#xff1a;界面设计、文件夹操作、常规文件操作。本文主要讲解界面设计&#xff0c;后续文章后讲解后两部分。 1、界面设计 最终的界面如下 1.1、创建类&#xff0c;并添加头文件 #include <QListWidget> #include…

spring boot3单模块项目工程搭建-上(个人开发模板)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 上文衔接 常规目录创建 common目录 exception.handle目录 result.handle目录 controller目录 service…

探索NDWI:归一化水体指数的意义与应用

随着遥感技术的不断发展&#xff0c;NDWI&#xff08;Normalized Difference Water Index&#xff0c;归一化水体指数&#xff09;作为一种重要的植被指数&#xff0c;被广泛应用于水资源管理、湿地监测和环境保护等领域。本文将介绍NDWI的意义、计算方法以及在不同领域的应用。…

什么是0-day漏洞,怎么防护0-day漏洞攻击

随着信息技术的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;其中0day漏洞攻击作为一种高级威胁手段&#xff0c;给企业和个人用户带来了极大的风险。下面德迅云安全就对0day漏洞攻击进行简单讲解下&#xff0c;并分享相应的一些安全措施&#xff0c;以期提高网络安全…

设计模式-创建型-抽象工厂模式-Abstract Factory

UML类图 工厂接口类 public interface ProductFactory {Phone phoneProduct();//生产手机Router routerProduct();//生产路由器 } 小米工厂实现类 public class XiaomiFactoryImpl implements ProductFactory {Overridepublic Phone phoneProduct() {return new XiaomiPhone…

【Interconnection Networks 互连网络】Flattened Butterfly 扁平蝶形拓扑

Flattened Butterfly 扁平蝶形拓扑 1. 传统蝶形网络 Butterfly Topology2. 扁平蝶形拓扑 Flattened Butterfly3.On-Chip Flattened Butterfly 扁平蝶形拓扑应用于片上网络 Flattened Butterfly 扁平蝶形拓扑 扁平蝶形拓扑是一种经济高效的拓扑&#xff0c;适用于高基数路由器…

向量数据库的崛起:如何改变数据存储与机器学习的未来

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

基于 Spring Boot 博客系统开发(一)

基于 Spring Boot 博客系统开发&#xff08;一&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握SprIng Boot 框架及相关技术的使用。&#x1f913;&#x1f913;&#x1f913; 本系统开发所需的环境及相关软件 操作系统&#xff1a;Windows Java…

20240330-1-词嵌入模型w2v+tf-idf

Word2Vector 1.什么是词嵌入模型&#xff1f; 把词映射为实数域向量的技术也叫词嵌⼊ 2.介绍一下Word2Vec 谷歌2013年提出的Word2Vec是目前最常用的词嵌入模型之一。Word2Vec实际是一种浅层的神经网络模型&#xff0c;它有两种网络结构&#xff0c;分别是连续词袋&#xff…

iOS 全平台矢量动画库:体积小巧、功能丰富 | 开源日报 No.227

airbnb/lottie-ios Stars: 24k License: NOASSERTION lottie-ios 是一个用于在 iOS 平台上本地渲染 After Effects 矢量动画的库。 该项目主要功能、关键特性、核心优势包括&#xff1a; 跨平台支持&#xff1a;可在 iOS, macOS, tvOS, visionOS, Android 和 Web 上使用实时渲…

NewStarCTF 2023 web

目录 week1 泄漏的秘密 Begin of Upload Begin of HTTP ErrorFlask Begin of PHP R!C!E! EasyLogin week2 游戏高手 include 0。0 ez_sql Unserialize&#xff1f; Upload again! R!!C!!E!! week3 Include &#x1f350; medium_sql POP Gadget GenShin wee…