USB开启ADB设置流程

ops/2024/9/19 11:19:08/ 标签: adb
adb调试选项">第一步:设置里打开adb调试选项

源码路径:packages/apps/Settings/src/com/android/settings/development/AdbPreferenceController.java

public void onAdbDialogConfirmed() {writeAdbSetting(true);
}

writeAdbSetting 函数所在源码路径:frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractEnableAdbPreferenceController.java

protected void writeAdbSetting(boolean enabled) {Settings.Global.putInt(mContext.getContentResolver(),Settings.Global.ADB_ENABLED, enabled ? ADB_SETTING_ON : ADB_SETTING_OFF);notifyStateChanged();
}private void notifyStateChanged() {LocalBroadcastManager.getInstance(mContext).sendBroadcast(new Intent(ACTION_ENABLE_ADB_STATE_CHANGED));
}

上述代码主要做了两个操作:

1)修改 Settings的 adb_enable 值

2)广播adb状态改变

setting应用中有监听adb状态广播:packages/apps/Settings/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java

其作用只是调用其注册的Controller的onAdbSettingChanged方法。

private final BroadcastReceiver mEnableAdbReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {for (AbstractPreferenceController controller : mPreferenceControllers) {if (controller instanceof AdbOnChangeListener) {((AdbOnChangeListener) controller).onAdbSettingChanged();}}}
};   
private void registerReceivers() {LocalBroadcastManager.getInstance(getContext()).registerReceiver(mEnableAdbReceiver, new IntentFilter(AdbPreferenceController.ACTION_ENABLE_ADB_STATE_CHANGED));final IntentFilter filter = new IntentFilter();filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED);getActivity().registerReceiver(mBluetoothA2dpReceiver, filter);
}

setting app 中 接口同目录的 VerifyAppsOverUsbPreferenceController类 继承了 AdbOnChangeListener 接口

@Override
public void updateState(Preference preference) {final RestrictedSwitchPreference restrictedPreference =(RestrictedSwitchPreference) preference;if (!shouldBeEnabled()) {restrictedPreference.setChecked(false);restrictedPreference.setDisabledByAdmin(null);restrictedPreference.setEnabled(false);return;}final EnforcedAdmin enforcingAdmin = mRestrictedLockUtils.checkIfRestrictionEnforced(mContext, UserManager.ENSURE_VERIFY_APPS, UserHandle.myUserId());if (enforcingAdmin != null) {restrictedPreference.setChecked(true);restrictedPreference.setDisabledByAdmin(enforcingAdmin);return;}restrictedPreference.setEnabled(true);final boolean checked = Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, SETTING_VALUE_ON)!= SETTING_VALUE_OFF;restrictedPreference.setChecked(checked);
}@Override
public void onAdbSettingChanged() {if (isAvailable()) {updateState(mPreference);}
}

上述代码只是做一些状态的改变。

第二步:开启ADB服务连接

修改settings里adb_enable的值时,会触发相关的监听。AdbService初始化时,监听了adb_enable 状态改变

private void initAdbState() {try {/** Use the normal bootmode persistent prop to maintain state of adb across* all boot modes.*/mIsAdbUsbEnabled = true;//containsFunction(//SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),// UsbManager.USB_FUNCTION_ADB);mIsAdbWifiEnabled = "1".equals(SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));// register observer to listen for settings changesmObserver = new AdbSettingsObserver();mContentResolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.ADB_ENABLED),  //监听 adb_enable值的改变false, mObserver);mContentResolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED),false, mObserver);} catch (Exception e) {Slog.e(TAG, "Error in initAdbState", e);}
}private class AdbSettingsObserver extends ContentObserver {private final Uri mAdbUsbUri = Settings.Global.getUriFor(Settings.Global.ADB_ENABLED);private final Uri mAdbWifiUri = Settings.Global.getUriFor(Settings.Global.ADB_WIFI_ENABLED);AdbSettingsObserver() {super(null);}@Overridepublic void onChange(boolean selfChange, @NonNull Uri uri, @UserIdInt int userId) {if (mAdbUsbUri.equals(uri)) {boolean shouldEnable = true;//(Settings.Global.getInt(mContentResolver,   //always enable usb adb//        Settings.Global.ADB_ENABLED, 0) > 0);FgThread.getHandler().sendMessage(obtainMessage(AdbService::setAdbEnabled, AdbService.this, shouldEnable,AdbTransportType.USB));} else if (mAdbWifiUri.equals(uri)) {boolean shouldEnable = (Settings.Global.getInt(mContentResolver,Settings.Global.ADB_WIFI_ENABLED, 0) > 0);FgThread.getHandler().sendMessage(obtainMessage(AdbService::setAdbEnabled, AdbService.this, shouldEnable,AdbTransportType.WIFI));}}
}

最终调用 setAdbEnabled 来设置adb 状态,代码如下:

private void startAdbd() {SystemProperties.set(CTL_START, ADBD);
}private void stopAdbd() {if (!mIsAdbUsbEnabled && !mIsAdbWifiEnabled) {SystemProperties.set(CTL_STOP, ADBD);}
}private void setAdbEnabled(boolean enable, byte transportType) {if (DEBUG) {Slog.d(TAG, "setAdbEnabled(" + enable + "), mIsAdbUsbEnabled=" + mIsAdbUsbEnabled+ ", mIsAdbWifiEnabled=" + mIsAdbWifiEnabled + ", transportType="+ transportType);}if (transportType == AdbTransportType.USB && enable != mIsAdbUsbEnabled) {mIsAdbUsbEnabled = enable;} else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) {mIsAdbWifiEnabled = enable;if (mIsAdbWifiEnabled) {if (!AdbProperties.secure().orElse(false) && mDebuggingManager == null) {// Start adbd. If this is secure adb, then we defer enabling adb over WiFi.SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");mConnectionPortPoller =new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);mConnectionPortPoller.start();}} else {// Stop adb over WiFi.SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "0");if (mConnectionPortPoller != null) {mConnectionPortPoller.cancelAndWait();mConnectionPortPoller = null;}}} else {// No changereturn;}if (enable) {startAdbd();} else {stopAdbd();}for (IAdbTransport transport : mTransports.values()) {try {transport.onAdbEnabled(enable, transportType);} catch (RemoteException e) {Slog.w(TAG, "Unable to send onAdbEnabled to transport " + transport.toString());}}if (mDebuggingManager != null) {mDebuggingManager.setAdbEnabled(enable, transportType);}
}

这里主要包括三步:

1)startAdbd 会设置 ctl.start 属性开启native层的adbd服务

2)调用transport.onAdbEnabled, 代码位于 UsbDeviceManager类

3)调用 mDebuggingManager.setAdbEnabled

UsbDeviceManager类路径位于 frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java

private static class AdbTransport extends IAdbTransport.Stub {private final UsbHandler mHandler;AdbTransport(UsbHandler handler) {mHandler = handler;}@Overridepublic void onAdbEnabled(boolean enabled, byte transportType) {if (transportType == AdbTransportType.USB) {mHandler.sendMessage(MSG_ENABLE_ADB, enabled);}}
}
@Override
public void handleMessage(Message msg) {switch (msg.what) {………………case MSG_ENABLE_ADB:setAdbEnabled(true); // alway true msg.arg1 == 1break;………………}
}

通过消息发送和处理后执行  setAdbEnabled 方法。

private void setAdbEnabled(boolean enable) {if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);if (enable) {setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_ADB);} else {setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, "");}setEnabledFunctions(mCurrentFunctions, true);updateAdbNotification(false);
}

这个主要做的是设置系统属性  persist.sys.usb.config = adb,然后调用 setEnabledFunctions 函数

@Override
protected void setEnabledFunctions(long usbFunctions, boolean forceRestart) {boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions);if (DEBUG) {Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + ", "+ "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);}if (usbDataUnlocked != mUsbDataUnlocked) {mUsbDataUnlocked = usbDataUnlocked;updateUsbNotification(false);forceRestart = true;}/*** Try to set the enabled functions.*/final long oldFunctions = mCurrentFunctions;final boolean oldFunctionsApplied = mCurrentFunctionsApplied;if (trySetEnabledFunctions(usbFunctions, forceRestart)) {return;}/*** Didn't work.  Try to revert changes.* We always reapply the policy in case certain constraints changed such as* user restrictions independently of any other new functions we were* trying to activate.*/if (oldFunctionsApplied && oldFunctions != usbFunctions) {Slog.e(TAG, "Failsafe 1: Restoring previous USB functions.");if (trySetEnabledFunctions(oldFunctions, false)) {return;}}/*** Still didn't work.  Try to restore the default functions.*/Slog.e(TAG, "Failsafe 2: Restoring default USB functions.");if (trySetEnabledFunctions(UsbManager.FUNCTION_NONE, false)) {return;}/*** Now we're desperate.  Ignore the default functions.* Try to get ADB working if enabled.*/Slog.e(TAG, "Failsafe 3: Restoring empty function list (with ADB if enabled).");if (trySetEnabledFunctions(UsbManager.FUNCTION_NONE, false)) {return;}/*** Ouch.*/Slog.e(TAG, "Unable to set any USB functions!");
}

setEnabledFunctions  函数主要调用 trySetEnabledFunctions 设置 usb的状态,如果设置返回失败,则一步步还原设置usb状态

private boolean trySetEnabledFunctions(long usbFunctions, boolean forceRestart) {String functions = null;if (usbFunctions != UsbManager.FUNCTION_NONE) {functions = UsbManager.usbFunctionsToString(usbFunctions);}mCurrentFunctions = usbFunctions;if (functions == null || applyAdbFunction(functions).equals(UsbManager.USB_FUNCTION_NONE)) {functions = UsbManager.usbFunctionsToString(getChargingFunctions());}functions = applyAdbFunction(functions);String oemFunctions = applyOemOverrideFunction(functions);if (!isNormalBoot() && !mCurrentFunctionsStr.equals(functions)) {setSystemProperty(getPersistProp(true), functions);}if ((!functions.equals(oemFunctions)&& !mCurrentOemFunctions.equals(oemFunctions))|| !mCurrentFunctionsStr.equals(functions)|| !mCurrentFunctionsApplied|| forceRestart) {Slog.i(TAG, "Setting USB config to " + functions);mCurrentFunctionsStr = functions;mCurrentOemFunctions = oemFunctions;mCurrentFunctionsApplied = false;/*** Kick the USB stack to close existing connections.*/setUsbConfig(UsbManager.USB_FUNCTION_NONE);if (!waitForState(UsbManager.USB_FUNCTION_NONE)) {Slog.e(TAG, "Failed to kick USB config");return false;}/*** Set the new USB configuration.*/setUsbConfig(oemFunctions);if (mBootCompleted&& (containsFunction(functions, UsbManager.USB_FUNCTION_MTP)|| containsFunction(functions, UsbManager.USB_FUNCTION_PTP))) {/*** Start up dependent services.*/updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));}if (!waitForState(oemFunctions)) {Slog.e(TAG, "Failed to switch USB config to " + functions);return false;}mCurrentFunctionsApplied = true;}return true;
}

这里主要包含两步:

1)调用 setUsbConfig 设置usb状态

2)调用 waitForState 判断状态是否设置成功

private void setUsbConfig(String config) {if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");/*** set the new configuration* we always set it due to b/23631400, where adbd was getting killed* and not restarted due to property timeouts on some devices*/setSystemProperty(USB_CONFIG_PROPERTY, config);
}

设置 sys.usb.config = adb

第二步的waitForState 方法如下:

private boolean waitForState(String state) {// wait for the transition to complete.// give up after 1 second.String value = null;for (int i = 0; i < 20; i++) {// State transition is done when sys.usb.state is set to the new configurationvalue = getSystemProperty(USB_STATE_PROPERTY, "");if (state.equals(value)) return true;SystemClock.sleep(50);}Slog.e(TAG, "waitForState(" + state + ") FAILED: got " + value);return false;
}

这个函数在 1s 内循环读取 sys.usb.state 的值,如果最后不是预期的值,则返回false。

最后是执行 mDebuggingManager.setAdbEnabled

public void setAdbEnabled(boolean enabled, byte transportType) {if (transportType == AdbTransportType.USB) {mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MESSAGE_ADB_ENABLED: AdbDebuggingHandler.MESSAGE_ADB_DISABLED);} else if (transportType == AdbTransportType.WIFI) {mHandler.sendEmptyMessage(enabled ? AdbDebuggingHandler.MSG_ADBDWIFI_ENABLE: AdbDebuggingHandler.MSG_ADBDWIFI_DISABLE);} else {throw new IllegalArgumentException("setAdbEnabled called with unimplemented transport type=" + transportType);}
}

对应消息处理函数:

public void handleMessage(Message msg) {if (mAdbKeyStore == null) {mAdbKeyStore = new AdbKeyStore();}switch (msg.what) {case MESSAGE_ADB_ENABLED:if (mAdbUsbEnabled) {break;}startAdbDebuggingThread();mAdbUsbEnabled = true;break;case MESSAGE_ADB_DISABLED:if (!mAdbUsbEnabled) {break;}stopAdbDebuggingThread();mAdbUsbEnabled = false;break;………………………………}
}private void startAdbDebuggingThread() {++mAdbEnabledRefCount;if (DEBUG) Slog.i(TAG, "startAdbDebuggingThread ref=" + mAdbEnabledRefCount);if (mAdbEnabledRefCount > 1) {return;}registerForAuthTimeChanges();mThread = new AdbDebuggingThread();mThread.start();mAdbKeyStore.updateKeyStore();scheduleJobToUpdateAdbKeyStore();}
startAdbDebuggingThread 开启 java层 adb线程开始接收处理控制命令。
第三步:native层服务及属性

上述服务完成后,java层的相关操作都已经完成,总结来看,java层做了三个操作

1、设置 ctl.start = adb 来打开adb服务。native层 adbd服务入口函数位于 system/core/adb/daemon/main.cpp 文件。

2、设置属性 persist.sys.usb.config = adb

3、设置属性 sys.usb.config = adb

java函数 waitForState 会读取 sys.usb.state 属性的值,如果不是 adb , 会返回false, 接着 setEnabledFunctions 会执行后续的代码将usb状态设置为空。那么 sys.usb.state 属性的值是在哪设置的呢?

在init进程中会监听各种属性的变化,并作出相应的处理,与adb设置相关的init主要有两个:

system/core/rootdir/init.usb.rc

system/core/rootdir/init.usb.configfs.rc

相关的操作中,会将 sys.usb.state 的值设置成  sys.usb.config 的值

on property:init.svc.adbd=stopped# setprop sys.usb.ffs.ready 0on property:sys.usb.config=adb && property:sys.usb.configfs=1start adbdon property:sys.usb.ffs.ready=1 && property:sys.usb.config=adb && property:sys.usb.configfs=1write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb"symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1write /config/usb_gadget/g1/UDC ${sys.usb.controller}setprop sys.usb.state ${sys.usb.config}on property:sys.usb.config=mtp && property:sys.usb.configfs=1write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp"symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1write /config/usb_gadget/g1/UDC ${sys.usb.controller}setprop sys.usb.state ${sys.usb.config}on property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1start adbdon property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp_adb"symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2write /config/usb_gadget/g1/UDC ${sys.usb.controller}setprop sys.usb.state ${sys.usb.config}on property:sys.usb.config=ptp && property:sys.usb.configfs=1write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp"symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1write /config/usb_gadget/g1/UDC ${sys.usb.controller}setprop sys.usb.state ${sys.usb.config}on property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1start adbd
adb自动开启">第四步:开机后如何保持adb自动开启

SystemServer 启动时,会调用 startOtherServices 启动 AdbService

private static final String ADB_SERVICE_CLASS ="com.android.server.adb.AdbService$Lifecycle";// Start ADB Debugging Service
t.traceBegin("StartAdbService");
try {mSystemServiceManager.startService(ADB_SERVICE_CLASS);
} catch (Throwable e) {Slog.e(TAG, "Failure starting AdbService");
}
t.traceEnd();

AdbService 启动代码如下:

public static class Lifecycle extends SystemService {private AdbService mAdbService;public Lifecycle(Context context) {super(context);}@Overridepublic void onStart() {mAdbService = new AdbService(getContext());publishBinderService(Context.ADB_SERVICE, mAdbService);}@Overridepublic void onBootPhase(int phase) {if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {mAdbService.systemReady();} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {FgThread.getHandler().sendMessage(obtainMessage(AdbService::bootCompleted, mAdbService));}}
}

创建 AdbService 服务对象并绑定到系统服务中,并在 onBootPhase 回调中处理 systemReady 和 bootCompleted 事件。

/*** Called in response to {@code SystemService.PHASE_ACTIVITY_MANAGER_READY} from {@code* SystemServer}.*/
public void systemReady() {if (DEBUG) Slog.d(TAG, "systemReady");/** Use the normal bootmode persistent prop to maintain state of adb across* all boot modes.*/mIsAdbUsbEnabled = containsFunction(SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, ""),UsbManager.USB_FUNCTION_ADB);boolean shouldEnableAdbUsb = mIsAdbUsbEnabled || SystemProperties.getBoolean(TestHarnessModeService.TEST_HARNESS_MODE_PROPERTY, false);mIsAdbWifiEnabled = "1".equals(SystemProperties.get(WIFI_PERSISTENT_CONFIG_PROPERTY, "0"));// make sure the ADB_ENABLED setting value matches the current statetry {Settings.Global.putInt(mContentResolver,Settings.Global.ADB_ENABLED, shouldEnableAdbUsb ? 1 : 0);Settings.Global.putInt(mContentResolver,Settings.Global.ADB_WIFI_ENABLED, mIsAdbWifiEnabled ? 1 : 0);} catch (SecurityException e) {// If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.Slog.d(TAG, "ADB_ENABLED is restricted.");}
}/*** Called in response to {@code SystemService.PHASE_BOOT_COMPLETED} from {@code SystemServer}.*/
public void bootCompleted() {if (DEBUG) Slog.d(TAG, "boot completed");if (mDebuggingManager != null) {mDebuggingManager.setAdbEnabled(mIsAdbUsbEnabled, AdbTransportType.USB);mDebuggingManager.setAdbEnabled(mIsAdbWifiEnabled, AdbTransportType.WIFI);}
}

读取 persist.sys.usb.config 属性值,判断是否包含 adb, 如果包含, 初始化 mIsAdbUsbEnabled = true 。 接着设置adb_enable的值,触发 AdbService 的 AdbSettingsObserver 监听。后续的设置流程与上述分析一致。


http://www.ppmy.cn/ops/111992.html

相关文章

只有IP地址没有域名怎么实现HTTPS访问?

&#x1f510; 实现IP地址HTTPS访问 &#x1f310; 确认公网IP地址 公网IP&#xff1a;确保你拥有一个公网IP地址&#xff0c;或者内网映射公网&#xff0c;这是实现HTTPS访问的前提。 &#x1f4dd; 选择证书颁发机构&#xff08;CA&#xff09; 选择CA&#xff1a;选择一个…

大数据-Hadoop-基础篇-第四章-HDFS(分布式文件存储)

目录 参考概念组成体系结构 数据块HDFS 文件读取HDFS 文件写入常用命令1. Is2. put3.moveFromLocal.4.get5.rm6. mkdir7.cp8. mv9.appendToFile10. cat javaAPI引入包创建文件夹 参考 经典大数据开发实战&#xff08;Hadoop &HDFS&Hive&Hbase&Kafka&Flume…

红帽9中nginx-源码编译php

什么是PHP-FPM&#xff1f; PHP-FPM(FastCGI Process Manager&#xff1a; FastCGI进程管理器)是一个实现了Fastcgi的程序&#xff0c;并且提供进程管理的功能。 进程包括master进程和worker进程。master进程只有一个&#xff0c;负责监听端口&#xff0c;接受来自web server 的…

【重学 MySQL】三十、数值类型的函数

【重学 MySQL】三十、数值类型的函数 基本函数角度与弧度互换函数三角函数指数与对数进制间的转换示例 基本函数 MySQL提供了一系列基本的数值函数&#xff0c;用于处理数学运算和数值转换。以下是一些常用的基本函数及其用法&#xff1a; 函数用法ABS(x)返回x的绝对值。SIGN…

手机玩机常识____展讯芯片刷机平台ResearchDownload的一些基本常识与问题解决

展讯ResearchDownload工具 展讯芯片的刷机工具--ResearchDownload下载工具"是一款专为用户设计的高效、便捷的下载管理软件&#xff0c;它能够帮助用户快速、稳定地从互联网上获取各种文件。这款工具以其强大的功能和良好的用户体验&#xff0c;在众多展讯芯片下载工具中脱…

springboot+security为什么@ControllerAdvice自定义的异常处理没有生效

意外遇到一个无语的bug。项目架构差不多&#xff0c;为什么本项目的ControllerAdvice自定义的异常处理没有生效&#xff0c;其他的就可以。 调试如下&#xff1a; 在捕获异常的位置debug ControllerAdvice 标注的类是否被 Spring 容器正确管理。 很明显&#xff0c;没有。找到…

QT --- 初识QT

一、通过代码构建helloworld界面 一般通过代码来构造界面的时候&#xff0c;通常会把构造界面的代码放到Widget/MainWindow的构造函数中。 Qt中每个类都有对应同名的头文件 上古时期&#xff0c;Qt用的是这种风格的文件。1998年之后&#xff0c;C标准成立了&#xff0c;C98标准…

《深度学习》深度学习 框架、流程解析、动态展示及推导

目录 一、深度学习 1、什么是深度学习 2、特点 3、神经网络构造 1&#xff09;单层神经元 • 推导 • 示例 2&#xff09;多层神经网络 3&#xff09;小结 4、感知器 神经网络的本质 5、多层感知器 6、动态图像示例 1&#xff09;一个神经元 相当于下列状态&…

软件工程知识点总结(7):软件项目管理

目录 1 软件项目管理 2 进度计划 2.1 WBS 2.2 WBS 工作分解结构 2.3 制定进度计划 ——Gantt 1 软件项目管理 软件项目管理是指软件生命周期中软件管理者所进行的一系列活动&#xff0c;其目的是在 一定的时间和预设范围内有效的利用人力、资源、技术和工具&#xff0c;使…

[数据集][目标检测]智慧交通铁路异物入侵检测数据集VOC+YOLO格式802张7类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;802 标注数量(xml文件个数)&#xff1a;802 标注数量(txt文件个数)&#xff1a;802 标注类别…

F12抓包11:UI自动化 - Recoder(记录器)

课程大纲 使用场景&#xff08;导入和导出&#xff09;: ① 测试的重复性工作&#xff0c;本浏览器录制并进行replay&#xff1b; ② 导入/导出录制脚本&#xff0c;移植后replay&#xff1b; ③ 导出给开发进行replay复现bug&#xff1b; ④ 进行前端性能分析。 1、录制脚…

Eureka原理与实践:构建高效的微服务架构

Eureka原理与实践&#xff1a;构建高效的微服务架构 引言 随着微服务架构的日益普及&#xff0c;服务的数量和复杂性不断增加&#xff0c;如何有效地管理这些服务成为了一个重要的挑战。Eureka&#xff0c;作为Netflix开源的服务发现组件&#xff0c;凭借其简单、健壮的特性&…

SpringBoot 消息队列RabbitMQ使用延迟消息插件 接收延迟消息

介绍 需要确保MQ已经安装好了延迟插件。 创建延迟交换机与队列 RabbitListener(bindings QueueBinding(value Queue(value "test.queue",durable "true"),exchange Exchange(value "test.fanout",delayed "true"),key {&quo…

23ai DGPDB,Oracle资源池战略的最后一块拼图

Oracle对资源池是有执念的&#xff01; 在我看来&#xff0c;这种执念一方面是应用架构的微服务化&#xff0c;数据库被拆分的越来越小&#xff0c;而服务器的硬件能力是不断提升的&#xff0c;CPU核心数、内存和存储的容量都按照摩尔定律在不断增加&#xff0c;这就使得数据库…

QUIC的loss detection学习

PTO backoff backoff 补偿 /ˈbkɒf/PTO backoff 是QUIC&#xff08;Quick UDP Internet Connections&#xff09;协议中的一种机制&#xff0c;用于处理探测超时&#xff08;Probe Timeout, PTO&#xff09;重传策略 它逐步增加探测超时的等待时间&#xff0c;以避免网络拥塞…

P1056 [NOIP2008 普及组] 排座椅(模拟)

1.用x,y数组存放切了几对学生&#xff0c;用数组的下标记录切的位置 2.按照题目要求k和l依次取出最大的数组的值&#xff0c;并将其变为-1&#xff0c; 再次循环取出第二大的值&#xff0c;之后所有下标为-1的的下标就是切的学生对多的 3.切的意思是把两个学生分开 #includ…

初学Linux(学习笔记)

初学Linux&#xff08;学习笔记&#xff09; 前言 本文跳过了Linux前期的环境准备&#xff0c;直接从知识点和指令开始。 知识点&#xff1a; 1.目录文件夹&#xff08;Windows&#xff09; 2.文件内容属性 3.在Windows当中区分文件类型是通过后缀&#xff0c;而Linux是通过…

如何理解BCEWithLogitsLoss()

1.示例1 logit[0.5 -1.0 2.0] targets[1 0 1]# δsigmoid(x) pδ(logits)[δ(0.5) δ(-1.0) δ(2.0)][0.6225 0.2689 0.8808]loss1 -[1 log(0.6225) 0 log(1 - 0.6225)] ≈ 0.4744 loss2 -[0 log(0.2689) 1 log(1 - 0.2689)] ≈ 0.3133 loss3 -[1 log(0.8808) 0 …

Linux tr命令

参考资料 【 tr 】コマンド――テキストファイルの文字を置換する&#xff0f;削除する【Linux】trコマンド使ってみた【trコマンド】 目录 一. 基本语法二. 替换2.1 匹配模式进行替换2.2 只支持字符的替换 三. 选项3.1 -d 删除指定字符3.2 -s 替换多个重复出现的字符为单个字…

new/delete和malloc/free到底有什么区别

new和malloc 文章目录 new和malloc前言一、属性上的区别二、使用上的区别三、内存位置的区别四、返回类型的区别五、分配失败的区别六、扩张内存的区别七、系统调度过程的区别总结 前言 new和malloc的知识点&#xff0c;作为一个嵌入式工程师是必须要了解清楚的。new和malloc的…