Android14 - Framework- Configuration的创建和更新

本文描述启动一个新进程ActivityFramworkConfiguration创建传导过程

首先我们知道所有Window容器继承于WindowContainerWindowContainer本身ConfigurationContainer子类于此同时WindowProcessController也是ConfigurationContainer子类ConfigurationContainer认为可以Window进程进行Configuration配置基本载体单位

我们启动一个Activity角度出发Configuration的传导过程

启动Activity过程调用ActivityTaskSupervisorrealStartActivityLocked方法

platform/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.javaboolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
	boolean andResume, boolean checkConfig) throws RemoteException {...if (checkConfig) {
		// Deferring resume here because we're going to launch new activity shortly.
		// We don't want to perform a redundant launch of the same record while ensuring
		// configurations and trying to resume top activity of focused root task.
		mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(),
				false /* markFrozenIfConfigChanged */, true /* deferResume */);
	}...
}

Activity启动场景checkConfigtrue

看ensureVisibilityAndConfig

platform/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.javaboolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,
		boolean markFrozenIfConfigChanged, boolean deferResume) {
	// First ensure visibility without updating the config just yet. We need this to know what
	// activities are affecting configuration now.
	// Passing null here for 'starting' param value, so that visibility of actual starting
	// activity will be properly updated.
	ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
			false /* preserveWindows */, false /* notifyClients */);	if (displayId == INVALID_DISPLAY) {
		// The caller didn't provide a valid display id, skip updating config.
		return true;
	}	// Force-update the orientation from the WindowManager, since we need the true configuration
	// to send to the client now.
	final DisplayContent displayContent = getDisplayContent(displayId);
	Configuration config = null;
	if (displayContent != null) {
		config = displayContent.updateOrientation(starting, true /* forceUpdate */);
	}
	// Visibilities may change so let the starting activity have a chance to report. Can't do it
	// when visibility is changed in each AppWindowToken because it may trigger wrong
	// configuration push because the visibility of some activities may not be updated yet.
	if (starting != null) {
		starting.reportDescendantOrientationChangeIfNeeded();
	}
	if (starting != null && markFrozenIfConfigChanged && config != null) {
		starting.frozenBeforeDestroy = true;
	}	if (displayContent != null) {
		// Update the configuration of the activities on the display.
		return displayContent.updateDisplayOverrideConfigurationLocked(config, starting,
				deferResume, null /* result */);
	} else {
		return true;
	}
}

调用了DisplayContentupdateOrientation注意这里第二个参数forceUpdatetrue强制更新

platform/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.javaConfiguration updateOrientation(WindowContainer<?> freezeDisplayWindow, boolean forceUpdate) {
	if (!mDisplayReady) {
		return null;
	}	Configuration config = null;
	if (updateOrientation(forceUpdate)) {
		// If we changed the orientation but mOrientationChangeComplete is already true,
		// we used seamless rotation, and we don't need to freeze the screen.
		if (freezeDisplayWindow != null && !mWmService.mRoot.mOrientationChangeComplete) {
			final ActivityRecord activity = freezeDisplayWindow.asActivityRecord();
			if (activity != null && activity.mayFreezeScreenLocked()) {
				activity.startFreezingScreen();
			}
		}
		config = new Configuration();
		computeScreenConfiguration(config);
	}	return config;
}

如果需要更新Orientation创建new Configuration()调用computeScreenConfiguration

platform/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java/**
 * Compute display configuration based on display properties and policy settings.
 * Do not call if mDisplayReady == false.
 */
void computeScreenConfiguration(Configuration config) {
	final DisplayInfo displayInfo = updateDisplayAndOrientation(config);
	final int dw = displayInfo.logicalWidth;
	final int dh = displayInfo.logicalHeight;
	mTmpRect.set(0, 0, dw, dh);
	config.windowConfiguration.setBounds(mTmpRect);
	config.windowConfiguration.setMaxBounds(mTmpRect);
	config.windowConfiguration.setWindowingMode(getWindowingMode());
	config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());	computeScreenAppConfiguration(config, dw, dh, displayInfo.rotation);	config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
			| ((displayInfo.flags & Display.FLAG_ROUND) != 0
			? Configuration.SCREENLAYOUT_ROUND_YES
			: Configuration.SCREENLAYOUT_ROUND_NO);	config.densityDpi = displayInfo.logicalDensityDpi;	config.colorMode =
			((displayInfo.isHdr() && mWmService.hasHdrSupport())
					? Configuration.COLOR_MODE_HDR_YES
					: Configuration.COLOR_MODE_HDR_NO)
					| (displayInfo.isWideColorGamut() && mWmService.hasWideColorGamutSupport()
					? Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_YES
					: Configuration.COLOR_MODE_WIDE_COLOR_GAMUT_NO);	// Update the configuration based on available input devices, lid switch,
	// and platform configuration.
	config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
	config.keyboard = Configuration.KEYBOARD_NOKEYS;
	config.navigation = Configuration.NAVIGATION_NONAV;	int keyboardPresence = 0;
	int navigationPresence = 0;
	final InputDevice[] devices = mWmService.mInputManager.getInputDevices();
	final int len = devices != null ? devices.length : 0;
	for (int i = 0; i < len; i++) {
		InputDevice device = devices[i];
		// Ignore virtual input device.
		if (device.isVirtual()) {
			continue;
		}		// Check if input device can dispatch events to current display.
		if (!mWmService.mInputManager.canDispatchToDisplay(device.getId(), mDisplayId)) {
			continue;
		}		final int sources = device.getSources();
		final int presenceFlag = device.isExternal()
				? WindowManagerPolicy.PRESENCE_EXTERNAL : WindowManagerPolicy.PRESENCE_INTERNAL;		if (mWmService.mIsTouchDevice) {
			if ((sources & InputDevice.SOURCE_TOUCHSCREEN) == InputDevice.SOURCE_TOUCHSCREEN) {
				config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
			}
		} else {
			config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
		}		if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
			config.navigation = Configuration.NAVIGATION_TRACKBALL;
			navigationPresence |= presenceFlag;
		} else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
				&& config.navigation == Configuration.NAVIGATION_NONAV) {
			config.navigation = Configuration.NAVIGATION_DPAD;
			navigationPresence |= presenceFlag;
		}		if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
			config.keyboard = Configuration.KEYBOARD_QWERTY;
			keyboardPresence |= presenceFlag;
		}
	}	if (config.navigation == Configuration.NAVIGATION_NONAV && mWmService.mHasPermanentDpad) {
		config.navigation = Configuration.NAVIGATION_DPAD;
		navigationPresence |= WindowManagerPolicy.PRESENCE_INTERNAL;
	}	// Determine whether a hard keyboard is available and enabled.
	// TODO(multi-display): Should the hardware keyboard be tied to a display or to a device?
	boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
	if (hardKeyboardAvailable != mWmService.mHardKeyboardAvailable) {
		mWmService.mHardKeyboardAvailable = hardKeyboardAvailable;
		mWmService.mH.removeMessages(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
		mWmService.mH.sendEmptyMessage(REPORT_HARD_KEYBOARD_STATUS_CHANGE);
	}	mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();	// Let the policy update hidden states.
	config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
	config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
	config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
	mWmService.mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
}

computeScreenAppConfiguration用来更新屏幕尺寸密度、rotation

platform/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java/** Compute configuration related to application without changing current display. */
private void computeScreenAppConfiguration(Configuration outConfig, int dw, int dh,
		int rotation) {
	final DisplayPolicy.DecorInsets.Info info =
			mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh);
	// AppBounds at the root level should mirror the app screen size.
	outConfig.windowConfiguration.setAppBounds(info.mNonDecorFrame);
	outConfig.windowConfiguration.setRotation(rotation);
	outConfig.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;	final float density = mDisplayMetrics.density;
	outConfig.screenWidthDp = (int) (info.mConfigFrame.width() / density + 0.5f);
	outConfig.screenHeightDp = (int) (info.mConfigFrame.height() / density + 0.5f);
	outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale);
	outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale);
	outConfig.screenLayout = computeScreenLayout(
			Configuration.resetScreenLayout(outConfig.screenLayout),
			outConfig.screenWidthDp, outConfig.screenHeightDp);	final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
	outConfig.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dw, dh);
	outConfig.windowConfiguration.setDisplayRotation(rotation);
}

回到ensureVisibilityAndConfig 获取Configuration调用displayContent.updateDisplayOverrideConfigurationLocked

platform/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java/**
 * Updates override configuration specific for the selected display. If no config is provided,
 * new one will be computed in WM based on current display info.
 */
boolean updateDisplayOverrideConfigurationLocked(Configuration values,
		ActivityRecord starting, boolean deferResume,
		ActivityTaskManagerService.UpdateConfigurationResult result) {	int changes = 0;
	boolean kept = true;	mAtmService.deferWindowLayout();
	try {
		if (values != null) {
			if (mDisplayId == DEFAULT_DISPLAY) {
				// Override configuration of the default display duplicates global config, so
				// we're calling global config update instead for default display. It will also
				// apply the correct override config.
				changes = mAtmService.updateGlobalConfigurationLocked(values,
						false /* initLocale */, false /* persistent */,
						UserHandle.USER_NULL /* userId */);
			} else {
				changes = performDisplayOverrideConfigUpdate(values);
			}
		}		if (!deferResume) {
			kept = mAtmService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
		}
	} finally {
		mAtmService.continueWindowLayout();
	}	if (result != null) {
		result.changes = changes;
		result.activityRelaunched = !kept;
	}
	return kept;
}

单个屏幕场景mDisplayId == DEFAULT_DISPLAY调用mAtmService.updateGlobalConfigurationLocked

platform/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java/** Update default (global) configuration and notify listeners about changes. */
int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
		boolean persistent, int userId) {	mTempConfig.setTo(getGlobalConfiguration());
	final int changes = mTempConfig.updateFrom(values);
	if (changes == 0) {
		return 0;
	}	...	// Note: certain tests currently run as platform_app which is not allowed
	// to set debug system properties. To ensure that system properties are set
	// only when allowed, we check the current UID.
	if (Process.myUid() == Process.SYSTEM_UID) {
		if (values.mcc != 0) {
			SystemProperties.set("debug.tracing.mcc", Integer.toString(values.mcc));
		}
		if (values.mnc != 0) {
			SystemProperties.set("debug.tracing.mnc", Integer.toString(values.mnc));
		}
	}	if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
		final LocaleList locales = values.getLocales();
		int bestLocaleIndex = 0;
		if (locales.size() > 1) {
			if (mSupportedSystemLocales == null) {
				mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
			}
			bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
		}
		SystemProperties.set("persist.sys.locale",
				locales.get(bestLocaleIndex).toLanguageTag());
		LocaleList.setDefault(locales, bestLocaleIndex);
	}	mTempConfig.seq = increaseConfigurationSeqLocked();	Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
	// TODO(multi-display): Update UsageEvents#Event to include displayId.
	mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());	// TODO: If our config changes, should we auto dismiss any currently showing dialogs?
	updateShouldShowDialogsLocked(mTempConfig);	AttributeCache ac = AttributeCache.instance();
	if (ac != null) {
		ac.updateConfiguration(mTempConfig);
	}	// Make sure all resources in our process are updated right now, so that anyone who is going
	// to retrieve resource values after we return will be sure to get the new ones. This is
	// especially important during boot, where the first config change needs to guarantee all
	// resources have that config before following boot code is executed.
	mSystemThread.applyConfigurationToResources(mTempConfig);	if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
		final Message msg = PooledLambda.obtainMessage(
				ActivityTaskManagerService::sendPutConfigurationForUserMsg,
				this, userId, new Configuration(mTempConfig));
		mH.sendMessage(msg);
	}	SparseArray<WindowProcessController> pidMap = mProcessMap.getPidMap();
	for (int i = pidMap.size() - 1; i >= 0; i--) {
		final int pid = pidMap.keyAt(i);
		final WindowProcessController app = pidMap.get(pid);
		ProtoLog.v(WM_DEBUG_CONFIGURATION, "Update process config of %s to new "
				+ "config %s", app.mName, mTempConfig);
		app.onConfigurationChanged(mTempConfig);
	}	final Message msg = PooledLambda.obtainMessage(
			ActivityManagerInternal::broadcastGlobalConfigurationChanged,
			mAmInternal, changes, initLocale);
	mH.sendMessage(msg);	Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RootConfigChange");
	// Update stored global config and notify everyone about the change.
	mRootWindowContainer.onConfigurationChanged(mTempConfig);
	Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);	Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
	return changes;
}

调用所用进程对应WindowProcessControlleronConfigurationChanged方法 这个方法最终会通知到客户端应用的所有Activity、Service等。随后通过broadcastGlobalConfigurationChanged发送ACTION_CONFIGURATION_CHANGED广播最后调用mRootWindowContainer.onConfigurationChanged(mTempConfig);这个通知服务端RootWindowContainer及其所有子窗口进行configuration更新

客户端传递路线参考序列图最终调用ConfigurationControllerhandleConfigurationChanged

platform/frameworks/base/core/java/android/app/ConfigurationController.java/**
 * Update the configuration to latest.
 * @param config The new configuration.
 * @param compat The new compatibility information.
 */
void handleConfigurationChanged(@Nullable Configuration config,
		@Nullable CompatibilityInfo compat) {
	int configDiff;
	boolean equivalent;	// Get theme outside of synchronization to avoid nested lock.
	final Resources.Theme systemTheme = mActivityThread.getSystemContext().getTheme();
	final ContextImpl systemUiContext = mActivityThread.getSystemUiContextNoCreate();
	final Resources.Theme systemUiTheme =
			systemUiContext != null ? systemUiContext.getTheme() : null;
	synchronized (mResourcesManager) {
		if (mPendingConfiguration != null) {
			if (!mPendingConfiguration.isOtherSeqNewer(config)) {
				config = mPendingConfiguration;
				updateDefaultDensity(config.densityDpi);
			}
			mPendingConfiguration = null;
		}		if (config == null) {
			return;
		}		// This flag tracks whether the new configuration is fundamentally equivalent to the
		// existing configuration. This is necessary to determine whether non-activity callbacks
		// should receive notice when the only changes are related to non-public fields.
		// We do not gate calling {@link #performActivityConfigurationChanged} based on this
		// flag as that method uses the same check on the activity config override as well.
		equivalent = mConfiguration != null && (0 == mConfiguration.diffPublicOnly(config));		if (DEBUG_CONFIGURATION) {
			Slog.v(TAG, "Handle configuration changed: " + config);
		}		final Application app = mActivityThread.getApplication();
		final Resources appResources = app.getResources();
		mResourcesManager.applyConfigurationToResources(config, compat);
		updateLocaleListFromAppContext(app.getApplicationContext());		if (mConfiguration == null) {
			mConfiguration = new Configuration();
		}
		if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
			return;
		}		configDiff = mConfiguration.updateFrom(config);
		config = applyCompatConfiguration();
		HardwareRenderer.sendDeviceConfigurationForDebugging(config);		if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
			systemTheme.rebase();
		}		if (systemUiTheme != null
				&& (systemUiTheme.getChangingConfigurations() & configDiff) != 0) {
			systemUiTheme.rebase();
		}
	}	final ArrayList<ComponentCallbacks2> callbacks =
			mActivityThread.collectComponentCallbacks(false /* includeUiContexts */);	freeTextLayoutCachesIfNeeded(configDiff);	if (callbacks != null) {
		final int size = callbacks.size();
		for (int i = 0; i < size; i++) {
			ComponentCallbacks2 cb = callbacks.get(i);
			if (!equivalent) {
				performConfigurationChanged(cb, config);
			}
		}
	}
}

mResourcesManager.applyConfigurationToResources(config, compat);config更新resourceManager

configDiff = mConfiguration.updateFrom(config);config = applyCompatConfiguration();更新本地config让后通过performConfigurationChanged传导所有AcivityService

无论WindowProcessControlleronConfigurationChanged还是mRootWindowContainer.onConfigurationChanged 首先执行基类ConfigurationContaineronConfigurationChanged

platform/frameworks/base/services/core/java/com/android/server/wm/ConfigurationContainer.java/**
 * Notify that parent config changed and we need to update full configuration.
 * @see #mFullConfiguration
 */
public void onConfigurationChanged(Configuration newParentConfig) {
	mResolvedTmpConfig.setTo(mResolvedOverrideConfiguration);
	resolveOverrideConfiguration(newParentConfig);
	mFullConfiguration.setTo(newParentConfig);
	// Do not inherit always-on-top property from parent, otherwise the always-on-top
	// property is propagated to all children. In that case, newly added child is
	// always being positioned at bottom (behind the always-on-top siblings).
	mFullConfiguration.windowConfiguration.unsetAlwaysOnTop();
	mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);
	onMergedOverrideConfigurationChanged();
	if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {
		// This depends on the assumption that change-listeners don't do
		// their own override resolution. This way, dependent hierarchies
		// can stay properly synced-up with a primary hierarchy's constraints.
		// Since the hierarchies will be merged, this whole thing will go away
		// before the assumption will be broken.
		// Inform listeners of the change.
		for (int i = mChangeListeners.size() - 1; i >= 0; --i) {
			mChangeListeners.get(i).onRequestedOverrideConfigurationChanged(
					mResolvedOverrideConfiguration);
		}
	}
	for (int i = mChangeListeners.size() - 1; i >= 0; --i) {
		mChangeListeners.get(i).onMergedOverrideConfigurationChanged(
				mMergedOverrideConfiguration);
	}
	for (int i = getChildCount() - 1; i >= 0; --i) {
		dispatchConfigurationToChild(getChildAt(i), mFullConfiguration);
	}
}

这个方法Configuration相关一些重要属性进行更新详述

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

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

相关文章

3.21总结

D - Shufflem Up 在扑克桌上&#xff0c;扑克玩家常常会玩一种叫做“洗筹码”的游戏。洗筹码是通过将两堆扑克筹码 S1 和 S2 进行交错堆叠来完成的&#xff0c;每堆筹码包含 C 个筹码。每堆筹码可能包含多种不同颜色的筹码。 实际的洗牌操作是通过将 S1 中的一枚筹码与 S2 中的…

为什么高铁提前三分钟停止检票?

为什么高铁提前三分钟停止检票&#xff1f; 高铁&#xff0c;作为现代交通方式的代表&#xff0c;以其高速、便捷、舒适的特点受到了广大乘客的青睐。然而&#xff0c;在乘坐高铁的过程中&#xff0c;乘客们可能会遇到一个问题&#xff1a;为什么高铁会提前三分钟停止检票呢&a…

jupyter notebook设置代码提示方法

在命令行运行以下代码&#xff1a; pip install jupyter_contrib_nbextensionsjupyter contrib nbextension install --userpip install jupyter_nbextensions_configuratorjupyter nbextensions_configurator enable --user &#xff08;有时安装第一行后会自动执行第二行&a…

【php基础】输出、变量、布尔类型、字符串

php基础补充 1. 输出2.和"的区别3.变量3.1变量的命名规则3.2 两个对象指向同一个值3.3 可变变量 4.变量的作用域5. 检测变量6. 布尔类型7.字符串定义与转义8.字符串常用函数9.常量 1. 输出 echo: 输出 print: 输出&#xff0c;输出成功返回1 print_r(): 输出数组 var_dum…

Vue 3中实现基于角色的权限认证实现思路

一、基于角色的权限认证主要步骤 在Vue 3中实现基于角色的权限认证通常涉及以下几个主要步骤&#xff1a; 定义角色和权限&#xff1a;首先需要在后端服务定义不同的角色和它们对应的权限。权限可以是对特定资源的访问权限&#xff0c;比如读取、写入、修改等。用户认证&#…

汽车价格的回归预测项目

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 问题描述 汽车价格预测是一个旨在预估二手车市场中汽车售价的问题。这个问题涉及到分析各种影响汽车价格的因素&#xff0c;如品牌、车龄、性能…

为什么大家都在“挺”鸿蒙?

试想某一天&#xff0c;应用软件能够在手机、电视、手表甚至汽车等设备上&#xff0c;实现无缝流转、纵享丝滑。 这不仅是畅想&#xff0c;而是鸿蒙正在布局的“遥遥领先”。 随着HarmonyOS NEXT鸿蒙星河版面向开发者开放申请、鸿蒙原生应用版图的基本成型&#xff0c;这个国…

多聆听,少评判

当朋友来找你倾诉、吐槽、诉苦&#xff0c;或是表达情绪的时候&#xff0c;你是怎样回应的&#xff1f; 许多人总有这样的习惯&#xff1a;每当听到朋友的倾诉&#xff0c;或者在网上看到别人诉苦时&#xff0c;第一反应往往是提建议&#xff1a;为什么你不试试这样做呢&#x…

ISIS骨干网连续性简述

默认情况下&#xff0c; 一、L1路由器是ISIS 普通区域内部路由器&#xff0c;只能与L1和L1-2路由器建立邻接关系&#xff0c;不能与L2路由器建立邻接关系。 二、L2路由器是骨干区域的路由器&#xff0c;L2路由器只能与其他 L2路由器同处一个区域&#xff0c;可与本区域的L2路由…

java JVM内存区域和对象创建,内存布局,访问

Java 虚拟机自动内存管理&#xff0c;不需要像C/C为每一个 new 操作去写对应的 delete/free 操作&#xff0c;不容易出现内存泄漏和内存溢出。但把内存控制权交给 Java 虚拟机&#xff0c;一旦出现内存泄漏和溢出问题&#xff0c;如不了解虚拟机怎样使用内存&#xff0c;将很难…

软考89-上午题-【操作系统】-同步与互斥

一、进程间的通信 在多道程序环境的系统中存在多个可以并发执行的进程&#xff0c;故进程间必然存在资源共享&#xff08;互斥&#xff09;和相互合作&#xff08;同步&#xff09;的问题。进程通信是指各个进程交换信息的过程。 同步是合作进程间的直接制约问题&#xff0c;互…

LeetCode 21 / 100

目录 矩阵矩阵置零螺旋矩阵旋转图像搜索二维矩阵 II LeetCode 73. 矩阵置零 LeetCode 54. 螺旋矩阵 LeetCode 48. 旋转图像 LeetCode 240. 搜索二维矩阵 II 矩阵 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为…

关于UDP协议

UDP协议是基于非连接的发送数据就是把数据包简单封装一下&#xff0c;然后从网卡发出去就可以&#xff0c;数据包之间没有状态上的联系&#xff0c;UDP处理方式简单&#xff0c;所以性能损耗非常少&#xff0c;对于CPU、内存资源的占用远小于TCP&#xff0c;但是对于网络传输过…

【OJ比赛日历】快周末了,不来一场比赛吗? #03.23-03.29 #16场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2024-03-23&#xff08;周六&#xff09; #7场比赛2024-03-24…

74CMS人才系统 CVE-2024-2561 RCE复现

Fofa语法 app"骑士-74CMS" 复现步骤 前期准备 主页长这样 需要先会员注册&#xff0c;注册为招聘者 复现 将poc贴入修改登录的Cookie信息和Token 访问查看 微信公众号 扫一扫关注CatalyzeSec公众号 我们一起来从零开始学习网络安全 加入我们的星球&#xff0c;…

zabbix企业微信的告警媒介配置

简介&#xff1a; Zabbix企业微信告警媒介可用于向特定群组成员发送提醒通知。 前提条件&#xff1a; 完成Zabbix告警平台的搭建后&#xff0c;需将群机器人添加至告警提醒群中。 企业微信群聊——右上角三个点——添加群机器人 保存好产生的webhook地址&#xff08;注意&…

2024.3.20 使用maven打包jar文件和保存到本地仓库

2024.3.20 使用maven打包jar文件和保存到本地仓库 使用maven可以很方便地打包jar文件和导入jar文件&#xff0c;同时还可以将该文件保存在本地仓库重复调用。 使用maven打包jar文件和保存到本地仓库 package打包文件。 install导入本地仓库。 使用maven导入jar文件 点击“…

CVE-2023-49442 jeecg-formdemocontroller JNDI代码执行漏洞分析

漏洞描述 JEECG(J2EE Code Generation) 是开源的代码生成平台&#xff0c;目前官方已停止维护。JEECG 4.0及之前版本中&#xff0c;由于 /api 接口鉴权时未过滤路径遍历&#xff0c;攻击者可构造包含 ../ 的url绕过鉴权。攻击者可构造恶意请求利用 jeecgFormDemoController.do…

P1596 [USACO10OCT] Lake Counting S(找连通块数量)

题目描述 Due to recent rains, water has pooled in various places in Farmer Johns field, which is represented by a rectangle of N x M (1 < N < 100; 1 < M < 100) squares. Each square contains either water (W) or dry land (.). Farmer John would l…

基于springboot的反诈宣传平台

技术&#xff1a;springbootmysqlvue 一、系统背景 反欺诈平台可以对公交信息进行集中管理&#xff0c;可以真正避免传统管理的缺陷。反欺诈平台是一款运用软件开发技术设计实现的应用系统&#xff0c;在信息处理上可以达到快速的目的&#xff0c;不管是针对数据添加&#xff…