解锁Android RemoteViews:跨进程UI更新的奥秘

一、RemoteViews 简介

在 Android 开发的广阔领域中,RemoteViews 是一个独特且重要的概念,它为开发者提供了一种在其他进程中显示视图结构的有效方式。从本质上讲,RemoteViews 并非传统意义上在当前应用进程内直接渲染和操作的 View,而是属于 SystemServer 进程的特殊 View 结构。

想象一下,在开发一个音乐播放应用时,我们希望在通知栏中展示播放控制界面,或者创建一个桌面小部件来快速启动播放、暂停等操作。这些场景下,通知栏和桌面小部件的界面并非在我们应用自身的进程中直接显示,而是运行在系统的 SystemServer 进程中。这时,RemoteViews 就发挥了关键作用,它允许我们在其他进程中展示特定的视图结构,实现跨进程的界面显示和交互。

由于 RemoteViews 是在其他进程中显示,其更新机制与普通 View 有很大不同。普通 View 可以在当前进程中直接通过 findViewById 获取控件并进行属性修改等操作,而 RemoteViews 为了实现跨进程更新界面,提供了一组基础操作方法 。这些方法是 View 全部方法的子集,大部分是通过反射来完成的。例如,我们无法像操作普通 TextView 那样直接调用 setText 方法来设置文本,而是需要使用 RemoteViews 提供的 setTextViewText 方法,传入对应的 viewId 和文本内容来实现。

二、RemoteViews 的使用场景

2.1 通知栏(Notification)

在通知栏中,RemoteViews 主要用于自定义通知的布局,使通知呈现出更丰富的内容和交互形式。比如在音乐播放应用中,通知栏不仅可以显示歌曲名称、歌手信息,还能添加播放、暂停、上一曲、下一曲等按钮,方便用户在不打开应用的情况下控制音乐播放 。下面通过代码示例来展示如何使用 RemoteViews 自定义通知栏布局:

// 1. 创建RemoteViews对象,加载自定义布局
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
// 2. 设置布局中的文本内容
remoteViews.setTextViewText(R.id.notification_title, "新消息提醒");
remoteViews.setTextViewText(R.id.notification_content, "您有一条新的消息,请查看。");
// 3. 设置布局中的图片
remoteViews.setImageViewResource(R.id.notification_icon, R.drawable.notification_icon);
// 4. 设置按钮的点击事件
Intent intent = new Intent(this, NotificationClickReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notification_button, pendingIntent);
// 5. 创建通知构建器
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID).setSmallIcon(R.drawable.ic_notification_small).setContent(remoteViews).setPriority(NotificationCompat.PRIORITY_DEFAULT);
// 6. 获取通知管理器并发送通知
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, builder.build());

上述代码中,首先通过RemoteViews加载了一个自定义的通知布局custom_notification_layout。然后,使用setTextViewText方法设置了通知的标题和内容,setImageViewResource方法设置了通知图标 。对于按钮的点击事件,通过创建一个Intent和PendingIntent,并使用setOnClickPendingIntent方法将其与通知布局中的按钮关联起来。最后,通过NotificationCompat.Builder构建通知,并使用NotificationManager发送通知。

2.2 桌面小部件(AppWidget)

桌面小部件是应用展示在用户桌面上的一个可视化组件,能提供简化信息和交互功能,像天气应用的桌面小部件可实时显示天气状况,日历应用的小部件能展示日程安排。使用 RemoteViews 开发桌面小部件,主要涉及布局定义、AppWidgetProvider 实现以及配置信息设置等步骤。具体如下:

  1. 定义 Widget 布局文件:在res/layout目录下创建布局文件,如widget_layout.xml,用于定义小部件的 UI。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/widget_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello, Widget!"android:textSize="18sp"android:textColor="#000" /><Buttonandroid:id="@+id/widget_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me" />
</LinearLayout>
  1. 创建 AppWidgetProvider 类:该类继承自AppWidgetProvider,用于处理小部件的生命周期事件和用户交互事件。
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
public class MyAppWidgetProvider extends AppWidgetProvider {@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {for (int appWidgetId : appWidgetIds) {// 创建RemoteViews对象,加载布局RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);// 设置按钮点击事件Intent intent = new Intent(context, MyAppWidgetProvider.class);intent.setAction("com.example.ACTION_BUTTON_CLICK");PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);// 更新小部件appWidgetManager.updateAppWidget(appWidgetId, views);}}@Overridepublic void onReceive(Context context, Intent intent) {super.onReceive(context, intent);if ("com.example.ACTION_BUTTON_CLICK".equals(intent.getAction())) {// 处理按钮点击事件// 例如:更新小部件内容}}
}
  1. 定义 AppWidgetProviderInfo 文件:在res/xml目录下创建文件,如widget_info.xml,用于指定小部件的布局、更新频率等信息。
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"android:minWidth="250dp"android:minHeight="100dp"android:updatePeriodMillis="1800000" <!--自动更新频率,单位为毫秒,这里设置为30分钟 -->android:initialLayout="@layout/widget_layout"android:resizeMode="horizontal|vertical"android:widgetCategory="home_screen" />
  1. 在 AndroidManifest.xml 中注册小部件:在AndroidManifest.xml文件中声明小部件的AppWidgetProvider。
<receiver android:name=".MyAppWidgetProvider"><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/widget_info" />
</receiver>

通过以上步骤,一个简单的桌面小部件就开发完成了。用户可以在主屏幕上添加该小部件,并与小部件进行交互,如点击按钮触发相应的操作 。

三、RemoteViews 的使用方法

3.1 创建 RemoteViews 对象

创建 RemoteViews 对象时,需要传入两个关键参数:当前应用的包名和对应的布局文件资源 ID。通过这两个参数,RemoteViews 能够准确关联到我们定义的布局文件,从而构建出相应的视图结构。例如:

RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_layout);

上述代码中,getPackageName()用于获取当前应用的包名,R.layout.custom_layout则是自定义布局文件的资源 ID。通过这行代码,我们成功创建了一个 RemoteViews 对象,并将其与custom_layout布局文件关联起来 。在实际开发中,布局文件可以包含各种支持的 View 组件,如 TextView、ImageView、Button 等,开发者可以根据需求进行灵活设计和布局。

3.2 设置 View 属性

RemoteViews 提供了一系列方法来设置 View 的属性,以满足不同的界面展示需求。以下是一些常用的设置 View 属性的方法:

  • setText:用于设置 TextView 或 Button 的文本内容。例如:
remoteViews.setTextViewText(R.id.text_view_id, "这是设置后的文本");

这里的R.id.text_view_id是 TextView 或 Button 在布局文件中的 ID,"这是设置后的文本"是要设置的具体文本内容。

  • setImageViewResource:用于设置 ImageView 或 ImageButton 的图片资源。例如:
remoteViews.setImageViewResource(R.id.image_view_id, R.drawable.icon);

其中[R.id].image_view_id是 ImageView 或 ImageButton 的 ID,R.drawable.icon是要设置的图片资源 ID。

  • setViewVisibility:用于设置 View 的可见性。可以设置为View.VISIBLE(可见)、View.INVISIBLE(不可见但占据空间)、View.GONE(不可见且不占据空间)。例如:
remoteViews.setViewVisibility(R.id.view_id, View.GONE);

R.id.view_id是要设置可见性的 View 的 ID 。

  • setTextColor:用于设置 TextView 或 Button 的文本颜色。例如:
remoteViews.setTextColor(R.id.text_view_id, Color.RED);

Color.RED表示红色,开发者可以根据需要选择不同的颜色值。

3.3 处理点击事件

由于 RemoteViews 运行在其他进程中,不能像普通 View 那样直接设置点击事件监听器 。为了实现点击事件的处理,需要借助 PendingIntent。PendingIntent 可以理解为一种 “延迟意图”,它允许我们在未来某个时刻执行特定的 Intent 操作。

具体实现步骤如下:

  1. 创建 Intent:定义点击事件触发后要执行的操作,例如启动一个 Activity、发送一个广播或启动一个 Service。
Intent intent = new Intent(this, TargetActivity.class);

这里TargetActivity.class是要启动的目标 Activity 。

  1. 创建 PendingIntent:通过 PendingIntent 的静态方法getActivity、getBroadcast或getService来创建 PendingIntent 对象,根据不同的需求选择相应的方法。
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

getBroadcast方法用于创建与广播相关的 PendingIntent,getService方法用于创建与服务相关的 PendingIntent 。

  1. 设置点击事件:使用 RemoteViews 的setOnClickPendingIntent方法,将 PendingIntent 与对应的 View 关联起来。
remoteViews.setOnClickPendingIntent(R.id.button_id, pendingIntent);

[R.id].button_id是要设置点击事件的按钮的 ID 。通过以上步骤,当用户点击关联了 PendingIntent 的 View 时,系统会在合适的时机执行 PendingIntent 中定义的操作,从而实现点击事件的处理。

3.4 应用 RemoteViews

在通知栏和桌面小部件中应用 RemoteViews 的步骤和使用的类有所不同,下面分别进行介绍:

  • 通知栏应用 RemoteViews
    1. 创建 RemoteViews 对象:如前文所述,创建并关联布局文件。
    1. 设置 RemoteViews 属性和点击事件:使用上述设置 View 属性和处理点击事件的方法进行相应设置。
    1. 创建 Notification 构建器:使用NotificationCompat.Builder来构建通知,并将 RemoteViews 设置为通知的内容。
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID).setSmallIcon(R.drawable.ic_notification_small).setContent(remoteViews).setPriority(NotificationCompat.PRIORITY_DEFAULT);

CHANNEL_ID是通知渠道 ID,在 Android 8.0 及以上版本需要设置通知渠道 。

  1. 发送通知:获取NotificationManager,并调用notify方法发送通知。
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId, builder.build());

notificationId是通知的唯一标识,用于区分不同的通知。

  • 桌面小部件应用 RemoteViews
    1. 定义小部件布局文件:在res/layout目录下创建布局文件,定义小部件的 UI 结构。
    1. 创建 AppWidgetProvider 类:继承自AppWidgetProvider,在onUpdate方法中处理小部件的更新逻辑。
public class MyAppWidgetProvider extends AppWidgetProvider {@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {for (int appWidgetId : appWidgetIds) {RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);// 设置属性和点击事件appWidgetManager.updateAppWidget(appWidgetId, views);}}
}
  1. 定义 AppWidgetProviderInfo 文件:在res/xml目录下创建文件,指定小部件的各种属性,如布局、最小尺寸、更新频率等。
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"android:minWidth="250dp"android:minHeight="100dp"android:updatePeriodMillis="1800000"android:initialLayout="@layout/widget_layout"android:resizeMode="horizontal|vertical"android:widgetCategory="home_screen" />
  1. 在 AndroidManifest.xml 中注册小部件:声明小部件的AppWidgetProvider。
<receiver android:name=".MyAppWidgetProvider"><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/widget_info" />
</receiver>

通过以上步骤,即可在通知栏和桌面小部件中成功应用 RemoteViews,实现丰富的界面展示和交互功能。

四、RemoteViews 的工作原理

4.1 跨进程通信机制

在 Android 系统中,进程间通信(IPC)是实现不同进程之间数据交互和功能调用的关键机制。而 Binder 机制则是 Android 中一种高效的 IPC 方式,RemoteViews 正是利用 Binder 机制来实现跨进程通信。

Binder 机制基于客户端 - 服务器(C/S)架构,主要由 Binder 驱动程序、ServiceManager、Server 端和 Client 端组成。Binder 驱动程序是 Linux 内核的一部分,负责处理跨进程通信的底层细节,如内存映射、数据传输等 。ServiceManager 是一个特殊的系统服务,它维护着一个服务列表,所有通过 Binder 进行通信的服务都需要在 ServiceManager 中注册,其他组件可以通过 ServiceManager 查询并获取服务的引用。

在 RemoteViews 的应用场景中,以通知栏为例,当我们在应用中创建一个包含 RemoteViews 的通知时,应用进程(Client 端)通过 Binder 机制将 RemoteViews 对象以及相关的操作指令发送到 SystemServer 进程(Server 端)中的 NotificationManagerService。NotificationManagerService 接收到这些信息后,根据 RemoteViews 中的包名等信息去获取该应用中的资源,然后进行相应的处理和显示。在这个过程中,Binder 机制确保了数据能够在不同进程之间安全、高效地传输 。同样,在桌面小部件的场景中,AppWidgetProvider 所在的应用进程与 SystemServer 进程中的 AppWidgetService 之间也是通过 Binder 机制进行通信,实现小部件的创建、更新等操作。

4.2 序列化与反序列化

为了在进程间传递 RemoteViews 对象及其相关操作,需要将其转换为可传输的字节流形式,这就涉及到序列化与反序列化。RemoteViews 实现了 Parcelable 接口,该接口提供了一种高效的序列化和反序列化机制,专门用于 Android 系统中的数据传输。

在序列化过程中,RemoteViews 将自身的状态信息,如布局资源 ID、设置的 View 属性以及点击事件等相关信息,按照 Parcelable 接口的规范写入到 Parcel 对象中。例如,当我们调用remoteViews.setTextViewText(R.id.text_view_id, “这是设置后的文本”);方法时,这个设置文本的操作以及相关的参数(如 View 的 ID 和文本内容)都会被封装到一个 Action 对象中,然后这个 Action 对象会被写入到 Parcel 中。

当 RemoteViews 对象被传输到目标进程(如 SystemServer 进程)后,目标进程会对接收到的 Parcel 进行反序列化操作。通过 Parcelable 接口的CREATOR成员,从 Parcel 中读取数据并重新构建出 RemoteViews 对象及其相关的操作信息,从而在目标进程中恢复 RemoteViews 的状态,以便进行后续的布局加载和更新操作 。

4.3 内部操作流程

当我们在应用中创建一个 RemoteViews 对象并对其进行一系列设置后,如设置 View 属性、添加点击事件等,这些操作并不会立即执行。RemoteViews 会将这些操作封装成一个个 Action 对象,并存储在一个列表中。例如,当调用setTextViewText方法时,会创建一个ReflectionAction对象(它是 Action 的子类,用于通过反射调用 View 的方法),并将其添加到 RemoteViews 的操作列表中。

接下来,当我们通过NotificationManager的notify方法或者AppWidgetManager的updateAppWidget方法提交更新时,RemoteViews 对象会通过 Binder 机制被传递到 SystemServer 进程。在 SystemServer 进程中,首先会根据 RemoteViews 中的布局资源 ID,使用LayoutInflater加载布局文件,创建出实际的 View 对象。然后,会遍历 RemoteViews 中的 Action 列表,依次执行每个 Action 的apply方法 。在apply方法中,会通过反射调用 View 的相应方法,从而实现对 View 属性的设置和点击事件的绑定等操作。例如,对于前面提到的ReflectionAction对象,其apply方法会反射调用 View 的setText方法,将设置的文本内容显示在对应的 TextView 上。

以一个简单的通知栏更新场景为例,假设我们创建了一个 RemoteViews 对象,并设置了 TextView 的文本和一个按钮的点击事件。当调用NotificationManager.notify方法后,RemoteViews 对象被传递到 SystemServer 进程,系统先加载布局文件创建出包含 TextView 和按钮的 View 结构,然后执行setText操作的 Action,将 TextView 的文本设置为指定内容,再执行设置按钮点击事件的 Action,将按钮与对应的 PendingIntent 绑定,这样当用户点击通知栏中的按钮时,就能触发相应的操作。

五、RemoteViews 的局限性

5.1 支持的 View 类型有限

RemoteViews 并非支持所有的 View 和布局类型,这是其在使用过程中需要特别注意的一点。目前,RemoteViews 支持的布局类型主要有 FrameLayout、LinearLayout、RelativeLayout、GridLayout 。在 View 类型方面,支持 AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView、AdapterViewFlipper、ViewStub 等。然而,它不支持自定义 View 及其子类 。例如,如果开发者尝试在 RemoteViews 中使用自定义的 View,如继承自 View 并实现了特殊绘制逻辑和交互功能的自定义控件,会抛出InflateException异常,导致布局加载失败。这就要求开发者在设计布局时,充分考虑 RemoteViews 的支持范围,避免使用不支持的 View 类型,以确保应用的稳定性和兼容性。

5.2 事件处理的限制

在事件处理方面,RemoteViews 存在明显的局限性。它不能像普通 View 那样直接设置点击事件监听器,例如无法使用setOnClickListener方法来处理点击事件。这是因为 RemoteViews 运行在其他进程中,直接设置点击事件监听器会涉及到跨进程通信的复杂问题,并且可能带来安全风险。为了实现点击等交互功能,RemoteViews 需要借助PendingIntent来实现。通过PendingIntent,可以将一个 Intent 操作封装起来,并在未来某个时刻由系统触发执行 。虽然这种方式能够实现基本的交互需求,但相比于普通 View 的事件处理方式,它的灵活性和实时性较差。例如,在处理复杂的事件逻辑时,使用PendingIntent可能会导致代码结构变得复杂,难以维护。而且,由于PendingIntent是在未来某个不确定的时刻执行,对于一些需要实时反馈的交互场景,可能无法满足需求。

5.3 性能开销

RemoteViews 在实现跨进程通信和视图更新的过程中,不可避免地会带来一定的性能开销。首先,由于 RemoteViews 需要通过 Binder 机制进行跨进程通信,在数据传输过程中,会涉及到序列化和反序列化操作,这会消耗一定的时间和系统资源。特别是当布局文件较大或者包含较多的操作指令时,序列化和反序列化的时间开销会更加明显,可能导致界面更新的延迟 。其次,在 SystemServer 进程中,加载布局文件和执行一系列的操作指令也需要消耗 CPU 和内存资源。如果频繁地更新 RemoteViews,可能会导致系统资源的紧张,影响应用的整体性能,甚至出现卡顿现象。例如,在一个频繁更新通知栏的应用中,如果每次更新都包含大量的 View 属性设置和复杂的布局,可能会导致通知栏的响应速度变慢,影响用户体验。因此,在使用 RemoteViews 时,开发者需要充分考虑性能因素,尽量优化布局和操作指令,减少不必要的更新,以提高应用的性能。

六、总结

RemoteViews 作为 Android 开发中实现跨进程界面展示和交互的重要工具,在通知栏和桌面小部件等场景中发挥着不可替代的作用。通过 RemoteViews,开发者能够突破进程的限制,为用户提供更加丰富和便捷的交互体验,如在通知栏中实现音乐播放控制,在桌面小部件上展示实时信息等。

尽管 RemoteViews 存在支持的 View 类型有限、事件处理不够灵活以及性能开销等局限性,但在合适的应用场景下,这些问题可以通过合理的设计和优化来缓解。例如,在布局设计时,充分考虑 RemoteViews 支持的 View 类型,避免使用不支持的自定义 View;在处理点击事件时,巧妙利用 PendingIntent 来实现基本的交互需求;在性能优化方面,尽量减少不必要的布局更新和复杂操作,以提高应用的响应速度 。

对于 Android 开发者来说,掌握 RemoteViews 的使用方法和工作原理,能够极大地拓展应用的功能边界,提升应用的用户体验。在未来的开发中,随着 Android 系统的不断演进,我们也期待 RemoteViews 能够不断完善和发展,为开发者提供更多的便利和更强大的功能。希望开发者们在实际项目中,积极探索 RemoteViews 的应用,充分发挥其优势,打造出更加出色的 Android 应用。

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

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

相关文章

常见webshell工具的流量特征

1、蚁剑 1.1、蚁剑webshell静态特征 蚁剑中php使用assert、eval执行&#xff1b;asp只有eval执行&#xff1b;在jsp使用的是Java类加载&#xff08;ClassLoader&#xff09;&#xff0c;同时会带有base64编码解码等字符特征。 1.2、蚁剑webshell动态特征 查看流量分析会发现…

爬虫系列之【数据解析之bs4】《四》

目录 前言 一、用法详解 1.1 获取标签内容 1.2 获取标签属性 1.3 获取标签包裹的文本内容 1.4 获取标签列表 1.5 css 选择器&#xff1a;select 二、实战案例 完整代码 前言 HTML数据解析 1、正则 2、xpath&#xff08;居多&#xff09; 3、css 选择器&#xff08;bs…

Java-实现PDF合同模板填写内容并导出PDF文件

可用于公司用户合同导出pdf文件 效果图 一、导入所需要jar包 <!--生成PDF--><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.11</version></dependency><dependency&…

【人工智能】GPT-4 vs DeepSeek-R1:谁主导了2025年的AI技术竞争?

前言 2025年&#xff0c;人工智能技术将迎来更加激烈的竞争。随着OpenAI的GPT-4和中国初创公司DeepSeek的DeepSeek-R1在全球范围内崭露头角&#xff0c;AI技术的竞争格局开始发生变化。这篇文章将详细对比这两款AI模型&#xff0c;从技术背景、应用领域、性能、成本效益等多个方…

前端开发10大框架深度解析

摘要 在现代前端开发中&#xff0c;框架的选择对项目的成功至关重要。本文旨在为开发者提供一份全面的前端框架指南&#xff0c;涵盖 React、Vue.js、Angular、Svelte、Ember.js、Preact、Backbone.js、Next.js、Nuxt.js 和 Gatsby。我们将从 简介、优缺点、适用场景 以及 实际…

【MySQL】索引(页目录、B+树)

文章目录 1. 引入索引2. MySQL与磁盘交互的基本单位3. 索引的理解3.1 页目录3.2 B树 4. 聚簇索引、非聚簇索引5. 索引的操作5.1 索引的创建5.1.1 创建主键索引5.1.2 创建唯一索引5.1.3 普通索引的创建5.1.4 全文索引的创建 5.2 索引的查询5.3 删除索引 1. 引入索引 索引&#…

python-串口助手(OV7670图传)

代码 主python文件 import serial import serial.tools.list_ports import time import tkinter as tk from tkinter import ttk import numpy as np from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure import threadi…

筑牢网络安全防线:守护您的数据安全

在数字化时代&#xff0c;数据安全已成为企业和个人不容忽视的重要议题。近日印尼国家数据中心遭黑客袭击的事件&#xff0c;不仅扰乱了机场的移民检查&#xff0c;还影响了众多机构的服务运行。黑客利用恶意软件对数据中心进行攻击&#xff0c;索要巨额赎金&#xff0c;给印尼…

Vue 3 整合 WangEditor 富文本编辑器:从基础到高级实践

本文将详细介绍如何在 Vue 3 项目中集成 WangEditor 富文本编辑器&#xff0c;实现图文混排、自定义扩展等高阶功能。 一、为什么选择 WangEditor&#xff1f; 作为国内流行的开源富文本编辑器&#xff0c;WangEditor 具有以下优势&#xff1a; 轻量高效&#xff1a;压缩后仅…

FastGPT 引申:信息抽取到知识图谱的衔接流程

文章目录 信息抽取到知识图谱的衔接流程步骤1&#xff1a;原始信息抽取结果步骤2&#xff1a;数据标准化处理&#xff08;Python示例&#xff09;步骤3&#xff1a;Cypher代码动态生成&#xff08;Python驱动&#xff09; 关键衔接逻辑说明1. 唯一标识符生成规则2. 数据映射策略…

Webshell 入侵与防御全攻略

Webshell&#xff0c;是指攻击者上传到网站的远程控制后门&#xff0c;允许黑客像管理员一样远程控制网站&#xff0c;执行恶意命令&#xff0c;甚至完全接管网站。本文将带你深入了解 Webshell 的入侵方式以及相应的防御措施&#xff0c;帮助你加固自己的网站防线。 什么是 W…

NL2SQL-基于Dify+阿里通义千问大模型,实现自然语音自动生产SQL语句

本文基于Dify阿里通义千问大模型&#xff0c;实现自然语音自动生产SQL语句功能&#xff0c;话不多说直接上效果图 我们可以试着问他几个问题 查询每个部门的员工数量SELECT d.dept_name, COUNT(e.emp_no) AS employee_count FROM employees e JOIN dept_emp de ON e.emp_no d…

双链路提升网络传输的可靠性扩展可用带宽

为了提升网络传输的可靠性或增加网络可用带宽&#xff0c; 通常使用双链路冗余备份或者双链路聚合的方式。 本文介绍几种双链路网络通信的案例。 5GWiFi冗余传输 双Socket绑定不同网络接口&#xff1a;通过Android的ConnectivityManager绑定5G蜂窝网络和WiFi的Socket连接&…

Ubuntu22.04安装Ollama部署DeepSeek-R1:32B模型

一、环境准备 1.硬件要求 GPU: 至少 NVIDIA A30/A100 (显存 ≥ 24GB)内存: ≥ 64GB RAM存储: ≥ 100GB 可用空间 (模型文件约 60GB)2.软件依赖 # 验证NVIDIA驱动 nvidia-smi二、Ollama安装 方法 1:install.sh安装 运行一下安装命令: curl -fsSL https://ollama.com/inst…

LeetCode 解题思路 10(Hot 100)

解题思路&#xff1a; 上边&#xff1a; 从左到右遍历顶行&#xff0c;完成后上边界下移&#xff08;top&#xff09;。右边&#xff1a; 从上到下遍历右列&#xff0c;完成后右边界左移&#xff08;right–&#xff09;。下边&#xff1a; 从右到左遍历底行&#xff0c;完成后…

Checkpoint 模型与Stable Diffusion XL(SDXL)模型的区别

Checkpoint 模型与 Stable Diffusion XL&#xff08;SDXL&#xff09;模型 在功能、架构和应用场景上有显著区别&#xff0c;以下是主要差异的总结&#xff1a; 1. 基础架构与定位 Checkpoint 模型 是基于 Stable Diffusion 官方基础模型&#xff08;如 SD 1.4/1.5&#xff09;…

GCC RISCV 后端 -- C语言语法分析过程

在 GCC 编译一个 C 源代码时&#xff0c;先会通过宏处理&#xff0c;形成 一个叫转译单元&#xff08;translation_unit&#xff09;&#xff0c;接着进行语法分析&#xff0c;C 的语法分析入口是 static void c_parser_translation_unit(c_parser *parser); 接着就通过类似递…

第十五届蓝桥杯Scratch12月stema选拔赛真题—消失的水母

消失的水母 编程实现&#xff1a; 消失的水母。&#xff08;角色、背景非源素材&#xff09; 具体要求&#xff1a; 1、每次点击绿旗&#xff0c;水母说“请输入 2&#xff5e;10 的整数”&#xff0c;同时在舞台下方显示输入框&#xff0c;如图所示; 完整题目可点击下方链…

Redis设计与实现-数据结构

Redis数据结构 1、RedisObject对象2、简单动态字符串2.1 SDS定义2.2 SDS与C语言的区别2.3 SDS的空间分配策略2.3.1 空间预分配2.3.2 惰性空间释放 2.4 SDS的API 3、链表3.1 链表的定义3.2 链表的API 4、字典4.1 字典的定义4.2 哈希算法4.3 哈希表的扩缩4.3.1 哈希表扩缩的判断依…

由麻省理工学院计算机科学与人工智能实验室等机构创建低成本、高效率的物理驱动数据生成框架,助力接触丰富的机器人操作任务

2025-02-28&#xff0c;由麻省理工学院计算机科学与人工智能实验室&#xff08;CSAIL&#xff09;和机器人与人工智能研究所的研究团队创建了一种低成本的数据生成框架&#xff0c;通过结合物理模拟、人类演示和基于模型的规划&#xff0c;高效生成大规模、高质量的接触丰富型机…