Android Preference浅析(设置Setting)

各位,好久不见,最近时间较为充裕,更新一下博客。

本篇在我的理解、认识范围内,讲述一下Android中的Preference(破粉斯~)这玩意,常用于项目中的设置模块中。在工作中我也主要负责了设置模块相关问题。

首先我看了一些写的比较好的博客博文,也是本篇文章的参考,各位可以跳转进行学习,感谢以下博文:

Android Preference简单介绍-CSDN博客

Android系统应用之Settings_android settings-CSDN博客

Android中的Preference结构的设计与实现 - 浪里小白龙呼呼呼 - 博客园

接下来,我们通过几个方面了解,请看目录:

目录

一、前言

二、Preference是什么

三、Preference有什么用

四、Preference 的常见类型

五、Preference 的布局与样式定制

六、Preference 的数据存储与读取

七、Preference 与用户交互逻辑

八、关于PreferenceManager

九、工作中遇到的一些Preference问题解决与思考


 

一、前言

首先我们需要看一下官方的几个网址:

介绍Preference(官方把这玩意放在了:添加设置组件模块中,也可以看出在设置模块中最常用):设置  |  Views  |  Android Developers

Android原生设置代码:AndroidXRef

和一脸懵逼点进本文的你一样,刚开始我在Android原生设置代码(packages/apps/Settings)看到这个玩意,似控件又不似控件,也不理解这Google工程师是有什么*****,非要搞一套这个(就因为更方便的保存SP值吗?),而且这东西大致的使用场景就是系统设置中,像一些软件开发者、学生很少用到。

另外一点你可以在Android Studio中选择新建Setting Activity,他就是使用Preference进行实现的一个demo(但是有些版本AS没有(好像是高版本移除了))

二、Preference是什么

官方:无需与设备存储空间交互,也不需要管理界面,便能构建交互式设置画面。

基本定义:

Preference 在 Android 开发中是一种用于管理应用设置(所以其实在APP的单独设置中也常用)的框架组件(可以发现介绍的是一种组件,而非我们理所当然认为是一种控件,控件更偏向于UI、功能单一,而组件更加广义,涵盖数据处理等)。它为应用提供了一种标准化的方式来处理用户可配置的选项,这些选项可以是简单的布尔值(如开关设置)、文本值(如用户自定义名称),也可以是从一组固定值中选择的选项(如语言选择)。从本质上讲,Preference 是一种数据结构和视图的结合体,既包含了用户设置的具体数据,又定义了这些数据在用户界面上的显示和交互方式

要在Android应用程序中使用Preference,您需要在应用程序的XML资源文件中定义每个偏好设置的首选项元素。

每个首选项元素都具有唯一的键和显示给用户的值。

当用户更改任何偏好设置时,Android会自动保存更改,并在用户下次启动应用程序时恢复它们。

三、Preference有什么用

简化开发流程(你可以简单理解如果没有他你需要监听控件、写XML、写SP值存取等一系列操作)

在 Android 应用开发中,如果没有 Preference 框架,开发者需要手动创建和管理设置界面。这意味着要从最基础的布局设计开始,为每个设置选项创建对应的视图控件,如 TextView 用于显示设置标题,EditText 用于用户输入,CheckBox 用于开关选项等。然后,还需要编写代码来处理这些控件的事件,例如保存用户输入的值、响应开关状态的改变等。而 Preference 框架提供了标准化的流程,开发者只需在 XML 布局文件中定义 Preference 类型和相关属性,就能快速搭建设置界面,大大减少了开发时间和工作量。

确保代码结构清晰

由于 Preference 将设置数据和用户界面显示及交互紧密结合,代码结构更加清晰。开发者可以在一个相对独立的模块中处理与 Preference 相关的代码,包括初始化 Preference、监听 Preference 变化以及从存储中读取和保存 Preference 值等操作。这与应用的其他业务逻辑(如网络请求、数据处理等)相互分离,使得代码易于维护和扩展。

例如,当需要添加新的设置选项时,只需在 XML 布局文件中添加新的 Preference 元素,并在对应的代码中处理该 Preference 的初始化和事件监听,而不会影响到应用的其他功能代码。

数据持久化机制

Preference 利用 SharedPreferences 来实现数据持久化。当用户在设置界面修改 Preference 的值时,例如改变一个 CheckBoxPreference 的勾选状态或在 EditTextPreference 中输入新文本,这些值会自动保存到 SharedPreferences 文件中。SharedPreferences 是一种轻量级的键值对存储方式,适合存储应用的配置数据。它基于 XML 文件(在内部实现上),能够保证数据在应用的多次启动和关闭过程中保持稳定。

状态保持功能

除了数据的持久化存储,Preference 还能保持设置的状态。在应用运行过程中,可能会因为各种原因(如屏幕旋转、切换到后台再回到前台等)导致 Activity 或 Fragment 的重新创建。Preference 框架会确保在这些情况下,设置的状态不会丢失。例如,在一个具有夜间模式开关 Preference 的应用中,无论应用经历了多少次状态变化,只要用户开启或关闭了夜间模式,这个状态都会被准确地记录和恢复。

满足多样化需求

用户对应用的需求是多样化的,Preference 为用户提供了个性化应用的途径。通过各种类型的 Preference,用户可以根据自己的喜好和使用习惯来调整应用的功能和外观。

四、Preference 的常见类型

一般从组件名(很想叫它控件,但是严谨哈哈哈)可以知道他的大致用法、功能

官网上可以看到(翻译一下、去除了弃用的,常用重要标红):

CheckBoxPreference提供复选框小部件功能的首选项。
DialogPreference基于对话框的首选项基类
DropDownPreference

在下拉菜单中而不是在对话框中显示选项的列表首选项。

EditTextPreference

在对话框中显示EditText的对话首选项。

EditTextPreference.SimpleSummaryProvider

一个简单的androidx. preatice.Preatice.SummaryProvider实现EditTextPreection。

ListPreference

将条目的列表显示为对话框的首选项。

ListPreference.SimpleSummaryProvider

SummaryProvider实现。

MultiSelectListPreference

将条目的列表显示为对话框的首选项。

Preference

表示在首选项层次结构中显示给用户的单个设置的基本构建块。

Preference.BaseSavedState

用于管理首选项的实例状态的基类。

PreferenceCategory

用于对相似的首选项进行分组的容器。

PreferenceDataStore

一个要实现并提供给偏好框架的数据存储接口。

PreferenceDialogFragmentCompat

抽象基类,表示与DialogPreference关联的对话框。

PreferenceFragmentCompat

PreferenceFragmentCompat是使用首选项库的切入点。

PreferenceGroup多个首选项的容器
PreferenceHeaderFragmentCompat

PreferenceHeaderFragmentCompat实现了一个用于首选项的两窗格片段。

PreferenceManager

用于帮助从活动或XML创建首选项层次结构。

PreferenceManager.PreferenceComparisonCallback

回调类将由与PreessceScreen关联的androidx.回收器视图.小部件.回收器视图. Adapter使用,用于确定两个首选对象何时在语义和视觉上相同。

PreferenceManager.SimplePreferenceComparisonCallback

PreferenceComparisonCallback的基本实现,适合与默认的首选项类一起使用。

PreferenceScreen

表示设置屏幕的顶级容器。

PreferenceViewHolder

一个RecyclerView. ViewHolder类,它缓存与默认首选项布局关联的视图。

SeekBarPreference偏好基于SeekBarPreection,但使用支持偏好作为基础。
SwitchPreference

提供两状态可切换选项的Preection。

SwitchPreferenceCompat

提供两状态可切换选项的Preection。

TwoStatePreference

具有两个可选状态的首选项的通用基类,保存一个布尔值,并且可能具有基于当前状态启用/禁用的依赖首选项。

看看表现形式:

如果你想要了解某一个Preference相关属性、方法等,建议直接点击表格的链接跳转到官方文档查看,例如我需要了解一下SwitchPrefernce:

android:summaryOff

android:summaryOn

android:switchTextOff

android:switchTextOn

还有一些基本类型例如title、高度、key等

android:icon

此属性用于为 Preference 设置一个图标资源。该图标会显示在 Preference 的标题旁边

android:summary

是对 Preference 的简短说明。该文本会在标题(android:title)下方显示,一般用于更详细地描述 Preference 的功能、作用或设置后的效果。

android:title

定义了 Preference 在设置界面中的主要显示文本,是用户识别 Preference 的最直接依据。

android:key

为 Preference 提供一个唯一的标识符。在整个应用的设置体系中,每个 Preference 的android:key都应该是独一无二的。

在数据存储(如 SharedPreferences)中,作为存储和检索 Preference 值的键。

android:layout

允许开发者指定一个自定义的布局来替换 Preference 的默认布局。自定义布局必须遵循 Preference 布局的相关规则。(和待会讲的强相关)

android:fragment

当用户点击 Preference 时,此属性用于指定要启动的 Fragment。Fragment 是 Android 中用于构建灵活 UI 的组件,它可以包含自己的布局和逻辑。

android:order

用于确定 Preference 在 PreferenceScreen(设置屏幕)中的排列顺序。它是一个整数值,值越小,在屏幕上显示的位置越靠前。

android:enabled

控制 Preference 是否处于可用状态。当设置为true时,Preference 正常响应用户操作;当设置为false时,Preference 呈现灰色不可用状态,且不响应用户交互操作。

android:selectable

决定 Preference 是否可以被用户选中。对于大多数可交互的 Preference 类型(如 CheckBoxPreference、ListPreference 等),该属性默认为true

android:widgetLayout

用于指定一个自定义的布局来替换 Preference 默认的小部件(widget)布局。小部件布局通常包含了 Preference 用于实现交互功能的元素,如 CheckBoxPreference 中的复选框部分。

android:shouldDisableView

这是一个布尔属性,用于确定是否根据 Preference 的可用性(由enabled属性决定)来禁用整个视图。

android:persistent

用于确定 Preference 的值是否会被持久化存储。默认情况下,多数 Preference 的该属性为true

android:intent

当用户点击 Preference 时,可以通过此属性指定一个意图(Intent)。Intent 是 Android 中用于启动组件(如 Activity、Service、Broadcast Receiver)的机制。

以上是常用属性

以下较不常用

android:defaultValue

为 Preference 指定一个默认值。这个值会在以下两种情况下被使用:一是当 Preference 首次被创建时;二是当找不到存储中对应的值时(例如,存储数据被意外删除或损坏)。

android:clickable

含义:专门控制 Preference 是否可被点击。虽然enabled属性也与用户操作有关,但clickable属性更聚焦于点击操作本身。


android:dependency

用于创建 Preference 之间的依赖关系。通过指定另一个 Preference 的android:key,可以使当前 Preference 的可用性取决于被指定 Preference 的值。

五、Preference 的布局与样式定制

android:layout:允许开发者指定一个自定义的布局来替换 Preference 的默认布局。

所以在项目设置中会经常看到layout属性然后绑定一个res/layout/文件夹下的布局文件(要知道的是我们Preference文件都在res/xml中)

为了与应用的整体风格相匹配,我们往往需要对 Preference 的布局和样式进行定制。

  • 布局定制方面:可以通过创建自定义的 XML 布局文件来重新排列 Preference 在设置界面中的显示顺序和位置。比如,将相关的设置项分组并使用特定的布局方式来展示,增加界面的可读性。同时,还可以添加额外的视图元素,如分割线、标题等,以提升视觉效果。

  • 样式定制方面:可以修改 Preference 的文本颜色、背景颜色、字体大小等样式属性。对于不同类型的 Preference,也可以分别设置其特定的样式,例如,将 CheckBoxPreference 的复选框大小或颜色修改得更符合应用的设计风格。这可以通过在主题(Theme)中定义样式或者直接在布局文件中使用属性来实现。

例如在设置源码中:/packages/apps/Settings/res/xml/wifi_settings.xml

 <PreferenceCategoryandroid:key="connected_access_point"android:layout="@layout/preference_category_no_label"/><PreferenceCategoryandroid:key="access_points"android:layout="@layout/preference_category_no_label"/>

 我们就可以去layout找preference_category_no_label这个布局:

/packages/apps/Settings/res/layout/preference_category_no_label.xml

它定义了一个Space视图组件。Space是 Android 提供的一种用于在布局中创建空白间隔空间的视图,其主要作用是在布局的不同元素之间添加一定的间距,以实现更好的视觉布局效果。

<Space xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="0dp" />

六、Preference 的数据存储与读取

了解 Preference 的数据是如何存储和读取的对于实现稳定的设置功能至关重要。

  • 存储机制:Android 系统通常使用 SharedPreferences 来存储 Preference 的数据。这是一种轻量级的键值对存储方式,每个 Preference 都有一个对应的键,其值可以是各种基本数据类型,如布尔型、字符串型、整型等。当用户修改 Preference 的值时,系统会自动将新的值更新到 SharedPreferences 文件中。

  • 读取过程在应用需要获取 Preference 的值时,它会通过相应的键从 SharedPreferences 文件中读取。例如,在启动应用时,需要根据之前用户设置的字体大小来显示文本,就可以从存储中读取该值并应用到文本视图中。同时,要注意处理读取数据可能出现的异常情况,如文件不存在或者数据类型不匹配等问题。

可以重温一下SharedPreferences,看我写的一个简单示例:

Android Studio初学者实例:使用SharedPreferences存储来保存QQ登录信息_android保存登录案例-CSDN博客

七、Preference 与用户交互逻辑

Preference 不仅仅是静态的设置选项,它还涉及到与用户交互的复杂逻辑。

  • 值改变监听:当用户修改了 Preference 的值时,应用需要及时响应这些变化。可以通过设置 OnPreferenceChangeListener 来监听 Preference 值的改变事件。例如,当用户在设置中更改了音量大小的 Preference 值时,应用需要立即调整音频输出的音量,并可能需要保存这个新的设置状态。

  • 点击事件处理:除了值改变监听,某些 Preference 可能还有特定的点击事件逻辑。比如,点击某个帮助文档类型的 Preference 可能会打开一个包含详细帮助信息的新页面。这种点击事件可以通过在 Preference 的 XML 定义中或者在代码中设置 OnPreferenceClickListener 来实现,为用户提供更丰富的交互体验。

这时,我们可以提一下前面未提到的android:controller属性,在原生设置中也经常遇到

在 Android 的 Preference 体系中,android:controller属性是用于建立一种特殊的关联关系,它允许一个 Preference(通常是具有交互性质的,比如TwoStatePreference的子类)与另一个 View 或 Preference 建立连接。这种连接可以实现复杂的交互逻辑和视觉反馈机制,从而提升用户在设置界面的体验。

(一)实现视图联动

  • 与其他视图的联动

    • 当一个 Preference 设置了android:controller属性后,它可以和指定的视图进行联动。例如,在某些设置场景中,可能有一个开关 Preference(如CheckBoxPreference)和一个文本视图(TextView)。通过将开关 Preference 的android:controller指向文本视图,当开关状态改变时,可以触发文本视图的更新,比如改变文本的颜色或显示内容,以此来直观地反映开关状态的变化。

    • 从代码实现角度看,当 Preference 的状态发生变化时(例如通过用户操作触发了OnPreferenceChangeListener),系统会根据android:controller属性找到关联的视图,并通过相应的方法(如setText()setColor())对视图进行更新。

  • 与其他 Preference 的联动

    • 除了和普通视图联动,android:controller还能实现 Preference 之间的联动。例如,有一个主开关 Preference 和多个子设置 Preference。当主开关关闭时,可以通过android:controller属性将子设置 Preference 设置为不可用状态(通过改变其enabled属性),从而实现设置项之间的层级控制。

    • 这种联动在实现复杂的设置逻辑时非常有用。例如在系统设置中,可能存在 “Wi - Fi 高级设置” 选项,当 “Wi - Fi” 开关关闭时,“Wi - Fi 高级设置” 相关的 Preference 都应被禁用,通过android:controller属性就能轻松实现这种依赖关系的控制。

(二)控制显示和隐藏

  • 基于状态的显示隐藏

    • android:controller属性可用于根据另一个视图或 Preference 的状态来控制当前 Preference 的显示和隐藏。例如,在一个具有多种配置模式的应用设置中,有一个模式选择 Preference(如ListPreference),以及多个仅在特定模式下才需要显示的子设置 Preference。

    • 通过将子设置 Preference 的android:controller指向模式选择 Preference,并在代码中根据模式选择 Preference 的选中值来判断是否显示子设置 Preference(通过改变其visibility属性),可以实现动态的设置界面布局,避免用户被过多不相关的设置项干扰。

  • 优化用户界面布局

    • 在屏幕空间有限的移动设备上,合理控制设置项的显示和隐藏对于优化用户界面布局至关重要。通过android:controller实现的显示隐藏机制,可以使设置界面更加简洁明了。例如,在音乐播放应用的设置中,当 “均衡器” 开关关闭时,与均衡器相关的多个设置 Preference(如不同频段的增益设置)可以被隐藏,从而为用户提供更清晰的设置界面。

(三)协调数据更新

  • 数据一致性维护

    • 当存在多个相关的设置项时,android:controller有助于维护数据的一致性。例如,在一个应用中有一个 “同步设置” Preference 和多个与不同类型数据同步相关的子设置 Preference(如 “联系人同步”“日历同步” 等)。

    • 如果 “同步设置” Preference 被关闭,不仅要通过android:controller将子设置 Preference 设置为不可用,还要在代码中确保相关的数据同步操作不会被触发,从而保证设置数据和实际操作的一致性。

  • 跨组件数据更新

    • 在涉及多个组件(如 Activity、Fragment)的设置场景中,android:controller可以促进跨组件的数据更新。例如,一个设置 Activity 中有多个 Fragment,每个 Fragment 包含不同类型的 Preference。通过android:controller在不同 Fragment 的 Preference 之间建立联系,可以在一个 Fragment 中的 Preference 状态改变时,及时更新其他 Fragment 中的相关 Preference 和数据。

    • 这种跨组件的数据协调更新能够避免数据不一致问题,尤其是在复杂的多屏幕设置应用中,确保用户在不同设置页面看到的信息和可操作的设置项都是准确和最新的。

随便找了一个Controller类:/packages/apps/Settings/src/com/android/settings/inputmethod/VirtualKeyboardPreferenceController.java 可以看看都做了哪些事情

// 定义了一个名为VirtualKeyboardPreferenceController的类,它继承自AbstractPreferenceController并实现了PreferenceControllerMixin接口
public class VirtualKeyboardPreferenceController extends AbstractPreferenceControllerimplements PreferenceControllerMixin {// 用于管理输入法的管理器实例private final InputMethodManager mImm;// 设备策略管理器实例,用于管理设备的策略相关操作private final DevicePolicyManager mDpm;// 包管理器实例,用于获取应用程序的包相关信息private final PackageManager mPm;// 构造函数,用于初始化类的实例// 接收一个Context上下文对象作为参数public VirtualKeyboardPreferenceController(Context context) {super(context);// 通过上下文获取包管理器实例mPm = mContext.getPackageManager();// 通过上下文获取设备策略管理器实例mDpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);// 通过上下文获取输入法管理器实例mImm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);}// 判断该偏好设置是否可用的方法// 根据配置文件中的布尔值来确定是否显示虚拟键盘偏好设置@Overridepublic boolean isAvailable() {return mContext.getResources().getBoolean(R.bool.config_show_virtual_keyboard_pref);}// 获取偏好设置的键值的方法// 返回虚拟键盘偏好设置对应的键值@Overridepublic String getPreferenceKey() {return "virtual_keyboard_pref";}// 更新偏好设置状态的方法// 根据输入法的相关信息来更新偏好设置的摘要(summary)信息@Overridepublic void updateState(Preference preference) {// 获取当前启用的输入法列表final List<InputMethodInfo> imis = mImm.getEnabledInputMethodList();if (imis == null) {// 如果列表为空,设置偏好设置的摘要为默认的空摘要字符串preference.setSummary(R.string.summary_empty);return;}// 获取当前用户允许使用的输入法列表final List<String> permittedList = mDpm.getPermittedInputMethodsForCurrentUser();final List<String> labels = new ArrayList<>();// 遍历当前启用的输入法列表for (InputMethodInfo imi : imis) {// 判断输入法是否被组织允许使用final boolean isAllowedByOrganization = permittedList == null|| permittedList.contains(imi.getPackageName());if (!isAllowedByOrganization) {continue;}// 将允许使用的输入法的标签添加到labels列表中labels.add(imi.loadLabel(mPm).toString());}if (labels.isEmpty()) {// 如果允许使用的输入法标签列表为空,设置偏好设置的摘要为默认的空摘要字符串preference.setSummary(R.string.summary_empty);return;}// 获取双向格式化器实例,用于处理文本的双向显示格式final BidiFormatter bidiFormatter = BidiFormatter.getInstance();String summary = null;// 遍历允许使用的输入法标签列表,构建偏好设置的摘要信息for (String label : labels) {if (summary == null) {summary = bidiFormatter.unicodeWrap(label);} else {summary = mContext.getString(R.string.join_many_items_middle, summary,bidiFormatter.unicodeWrap(label));}}// 设置偏好设置的摘要为构建好的摘要信息preference.setSummary(summary);}
}

八、关于PreferenceManager、PreferenceScreen

PreferenceManager是 Android 中用于管理 Preference 相关操作的重要类。它作为一个核心的协调者,在应用的设置模块中起着关键作用,帮助开发者从 Activity 或 XML 文件中创建和管理 Preference 层次结构。

  public class MySettingsActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);PreferenceManager preferenceManager = getPreferenceManager();// 假设在res/xml/中有一个名为preferences.xml的文件preferenceManager.inflateFromResource(this, R.xml.preferences, null);}}

PreferenceScreen在 Android 的 Preference 框架中是一个顶级容器类,用于组织和管理一组 Preference。它是 Preference 层次结构中的根元素,定义了整个设置界面的布局和内容结构。

层次结构基础、管理显示顺序

可以对PreferenceScreen进行遍历,在实际工作中经常用到

PreferenceScreen preferenceScreen = (PreferenceScreen) getPreferenceManager().inflateFromResource(getActivity(), R.xml.fragment_preferences, null);
if (preferenceScreen!= null) {PreferenceScreenTraversal.traverse(preferenceScreen);
}

九、工作中遇到的一些Preference问题解决与思考

WLAN直连设备名称布局下方分割线会移动

在进入界面时,分割线由于summary加载前后,会发生移动

解决办法:summary预先占好位置

写在最后:本文大量借助了AI,查询了一些知识,甚至包括本文分为哪几个要点写,然后进行筛选重要点。大家一定要会利用AI,自从有AI工具我也很少看博客了,除非疑难杂症的报错等。

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

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

相关文章

鸿道Intewell操作系统架构介绍之Intewell-Hyper I 虚拟化构型

鸿道Intewell-Hyper I 虚拟化构型是鸿道Intewell-V虚拟化架构下的构型体系&#xff01;鸿道Intewell-V是科东软件自主研发的实时虚拟化操作系统&#xff0c;包括鸿道Intewell-Hyper I 和鸿道Intewell-Hyper II。鸿道Intewell-V可以实现多个操作系统在同一物理硬件上并行运行&am…

讲一讲 kafka 的 ack 的三种机制?

大家好&#xff0c;我是锋哥。今天分享关于【K讲一讲 kafka 的 ack 的三种机制&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 讲一讲 kafka 的 ack 的三种机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka的消息确认机制&…

多租户系统的应用架构

大家好&#xff0c;我是汤师爷~ 我们看下多租户系统的应用架构是如何从一层层构建起来的。 1、应用层设计 应用层的主要作用是为具体的用户场景提供应用服务&#xff0c;帮助用户在特定场景下完成操作。通过编排领域层的各项能力&#xff0c;实现SaaS产品的核心功能。应用层包…

波兰喜嘎嘎

之前做的一个项目&#xff0c;需要用c写一个服务去访问和控制硬件。这个服务是同事写的&#xff0c;今年年中离职了&#xff0c;很自然地&#xff0c;轮到我接手。 一、认知 我捣鼓了几天&#xff0c;勉强读懂一点原来的代码&#xff0c;并在原来基础上&#xff0c;做了一些修…

基于LORA的一主多从监测系统_4G模块上巴法云

临时添加一个更新&#xff0c;更换云平台为巴法云&#xff0c;事情的起因是因为阿里云这个老六&#xff0c;早上睡了一觉起来发短信告诉我云平台给我停了&#xff0c;得交钱&#xff0c;好嘛&#xff0c;不过也没办法现在这基本都收费&#xff0c;当然还有onenet可以用&#xf…

.NET Core WebApi第4讲:控制器、路由

一、控制器是什么&#xff1f; 1、创建一个空的API控制器&#xff1a;TestController.cs 2、里面有一个类叫TestController&#xff0c;把它叫做控制器 因为它继承了ControllerBase类&#xff0c;ControllerBase类里提供了一系列的方法&#xff0c;使得TestController这个类具…

Java面试经典 150 题.P55. 跳跃游戏(009)

本题来自&#xff1a;力扣-面试经典 150 题 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台https://leetcode.cn/studyplan/top-interview-150/ 题解&#xff1a; class Solution {public boolean canJump(int[] nums) {int…

计算机网络网络层笔记

互联网提供的两种服务 1.虚电路服务 2.数据报服务 需要记住的是现在只用第二种也就是数据报服务 网际协议IP 物理层的中断系统:转发器(hub) 链路层的中断系统:交换机 网络层的中断系统:路由器 网络层以上:网关 如上图所示,网关是用来访问其他的网段的一个接口,网关的地…

【热门主题】000015 大数据治理:开启数据价值新纪元

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…

CentOS8.5.2111(4.1)数据中心主DNS部署

【背景】 某公司的数据中心DC&#xff0c;要架设DNS服务器负责解析“学生姓名缩写.cqie”的域名解析工作。DNS服务器的FQDN&#xff08;完全正式域名标识&#xff09;为dns.姓名.cqie&#xff0c;IP地址为192.168.学号.66。要求为以下域名实现正反向域名解析服务。&#xff08…

【C/C++】模拟实现strlen

学习目标&#xff1a; 使用代码模拟实现strlen。 逻辑&#xff1a; strlen 需要输入一个字符串数组类型的变量&#xff0c;并且返回一个整型类型的数据。strlen 需要计算字符串数组有多少个元素。 代码1&#xff1a;使用计数器 #define _CRT_SECURE_NO_WARNINGS 1 #include&…

渗透测试-百日筑基—SQL注入篇时间注入绕过HTTP数据编码绕过—下

day8-渗透测试sql注入篇&时间注入&绕过&HTTP数据编码绕过 一、时间注入 SQL注入时间注入&#xff08;也称为延时注入&#xff09;是SQL注入攻击的一种特殊形式&#xff0c;它属于盲注&#xff08;Blind SQL Injection&#xff09;的一种。在盲注中&#xff0c;攻击…

Linux 文件内容显示

文件内容显示 浏览普通文件 文件内容查看 cat 命令 作用&#xff1a;查看文件内容&#xff0c;适合数据量较少 格式&#xff1a; cat -参数 文件名 参数&#xff1a; -n &#xff1a;显示行号&#xff0c;加上 -b &#xff1a;文件中所有非空行增加行号&#xff0…

ALIGN: Tuning Multi-mode Token-level Prompt Alignment across Modalities

文章汇总 当前的问题 目前的工作集中于单模提示发现&#xff0c;即一种模态只有一个提示&#xff0c;这可能不足以代表一个类[17]。这个问题在多模态提示学习中更为严重&#xff0c;因为视觉和文本概念及其对齐都需要推断。此外&#xff0c;仅用全局特征来表示图像和标记是不…

linux学习笔记 Ubuntu下的守护进程supervisor安装与多项目部署

我这里首先是在本地WSL上进行安装&#xff0c;WSL2的是ubuntu 24.04&#xff0c;之后又再正式环境的ubuntu 20.04上安装&#xff0c;再次记录一下。 1、首先安装supervisor apt install -y supervisor 2、创建配置文件 echo_supervisord_conf > /etc/supervisor/supervisor…

Linux特种文件系统--tmpfs文件系统前传:虚拟内存子系统

虚拟内存子系统是操作系统中的一个重要组成部分&#xff0c;它负责管理和优化计算机的内存使用。虚拟内存的概念允许操作系统为每一个进程创建一个虚拟地址空间&#xff0c;这个空间比实际物理内存要大得多。虚拟内存子系统通过将部分虚拟地址映射到物理内存&#xff0c;部分映…

【测试工具】通过Jmeter压测存储过程

目录 一、存储过程准备1.1、 建立空表1.2、 建立存储过程1.3、调试 二、测试工具准备三、工具配置及执行3.1、配置JDBC Connection Configuration&#xff1a;3.2、配置吞吐量控制器3.3、配置JDBC Request 一、存储过程准备 1.1、 建立空表 CREATE TABLE test_data ( id NUMB…

安宝特分享 | AR技术引领:跨国工业远程协作创新模式

在当今高度互联的工业环境中&#xff0c;跨国合作与沟通变得日益重要。然而&#xff0c;语言障碍常常成为高效协作的绊脚石。安宝特AR眼镜凭借其强大的多语言自动翻译和播报功能&#xff0c;正在改变这一局面&#xff0c;让远程协作变得更加顺畅。 01 多语言翻译优势 安宝特A…

vivado-vitis-2024.1 ps_hello_world 实验

实验环境 vivado&#xff1a;2024.1 vitis&#xff1a;2024.1 核心板&#xff1a;ZYNQ-7020 实验内容 实验PS端串口打印 "Hello world " 硬件配置 打开vivado2024&#xff0c;新建一个工程 点击 Create Block Design 开始IP配置 首先连接线 然后点击自动连接…