当前位置: 首页 > news >正文

Android广播机制

简介

        某个网络的IP范围是192.168.0.XXX,子网 掩码是255.255.255.0,那么这个网络的广播地址就是192.168.0.255。广播数据包会被发送到同一 网络上的所有端口,这样在该网络中的每台主机都将会收到这条广播。为了便于进行系统级别的消息通知,Android也引入了一套类似的广播消息机制。这是因为Android中的每个应用程序都可以对自己感 兴趣的广播进行注册,这样该程序就只会接收到自己所关心的广播内容,这些广播可能是来自 于系统的,也可能是来自于其他应用程序的。Android提供了一套完整的API,允许应用程序自 由地发送和接收广播。发送广播的方法其实之前稍微提到过,如果你记性好的话可能还会有印 象,就是借助我们第2章学过的Intent。而接收广播的方法则需要引入一个新的概念——广播接 收器(Broadcast Receiver)。广播接收器的具体用法将会在下一节中做介绍,这里我们先来了解一下广播的类型。Android中 的广播主要可以分为两种类型:标准广播有序广播

一、广播的方式

标准广播:

        标准广播 (Normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的广播 接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可言。 这种广播的效率会比较高,但同时也意味着它是无法被截断的。标准广播的工作流程如图所示。

有序广播:

        有序广播 (Ordered broadcasts)则是一种同步执行的广播,在广播发出之后,同一时刻只 会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广 播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以 先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接 收器就无法收到广播消息了。有序广播的工作流程如图所示。

二、动态注册监听网络变化

        Android内置了很多系统级别的广播,我们可以在应用程序中通过监听这些广播来得到各种系统 的状态信息。比如手机开机完成后会发出一条广播,电池的电量发生变化会发出一条广播,时 间或时区发生改变也会发出一条广播,等等。如果想要接收到这些广播,就需要使用广播接收 器,下面我们就来看一下它的具体用法。广播接收器可以自由地对自己感兴趣的广播进行注册,这样当有相应的广播发出时,广播接收 器就能够收到该广播,并在内部处理相应的逻辑。注册广播的方式一般有两种,在代码中注册(动态注册) 和在AndroidManifest.xml中注册(静态注册)。

三、动态注册

1.定义NetworkChangeReceived监听网络状态变化
第一种代码逻辑:

public class NetworkChangeReceived extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {boolean isConnected = isNetworkConnected(context);String statusMessage = isConnected ? "连接" : "断开";String networkType = NetworkType(context);Toast.makeText(context, "网络已" + statusMessage + ",类型" + networkType, Toast.LENGTH_SHORT).show();}}private boolean isNetworkConnected(Context context) {ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetwork = cm.getActiveNetworkInfo();return activeNetwork != null && activeNetwork.isConnectedOrConnecting();}private String NetworkType(Context context) {ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetwork = cm.getActiveNetworkInfo();return activeNetwork != null ? activeNetwork.getTypeName() : "未知";}
}/*代码解释*/// 定义一个BroadcastReceiver子类,用于监听网络状态变化
public class NetworkChangeReceived extends BroadcastReceiver {// 当接收到广播时调用此方法@Overridepublic void onReceive(Context context, Intent intent) {// 检查Intent的动作是否为网络连接状态改变if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {// 调用私有方法检查网络是否连接boolean isConnected = isNetworkConnected(context);// 根据网络连接状态构建提示消息String statusMessage = isConnected ? "连接" : "断开";// 获取网络类型String networkType = NetworkType(context);// 使用Toast显示网络状态和类型Toast.makeText(context, "网络已" + statusMessage + ",类型" + networkType, Toast.LENGTH_SHORT).show();}}// 私有方法,用于检查网络是否处于连接状态private boolean isNetworkConnected(Context context) {// 获取系统的ConnectivityManager服务ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);// 获取当前活动的网络信息NetworkInfo activeNetwork = cm.getActiveNetworkInfo();// 判断网络信息是否非空并且网络正在连接或已经连接return activeNetwork != null && activeNetwork.isConnectedOrConnecting();}// 私有方法,用于获取网络类型private String NetworkType(Context context) {// 获取系统的ConnectivityManager服务ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);// 获取当前活动的网络信息NetworkInfo activeNetwork = cm.getActiveNetworkInfo();// 如果网络信息非空,返回网络类型名;否则返回"未知"return activeNetwork != null ? activeNetwork.getTypeName() : "未知";}
}
第二种代码逻辑:

public class NetworkChangeReceived extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {Toast.makeText(context,checkNetworkConnectionAndGetType(context), Toast.LENGTH_SHORT).show();}}public static String checkNetworkConnectionAndGetType(Context context) {ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo info = cm.getActiveNetworkInfo();if (info != null && info.isConnectedOrConnecting()) {// 网络已连接,返回网络类型名称return "连接"+info.getTypeName();} else {// 未连接网络return "断开";}}
}/*代码解释*//*** NetworkChangeReceived 类,继承自 BroadcastReceiver,用于监听和响应网络状态变化的广播事件。*/
public class NetworkChangeReceived extends BroadcastReceiver {/*** 当接收到广播时调用此方法。* * @param context 上下文,提供了应用程序的环境信息。* @param intent Intent 对象,包含了广播的数据和动作。*/@Overridepublic void onReceive(Context context, Intent intent) {/*** 检查 Intent 的动作是否是网络状态改变的广播。* 如果是,则获取网络状态和类型的信息,并通过 Toast 显示给用户。*/if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {Toast.makeText(context, checkNetworkConnectionAndGetType(context), Toast.LENGTH_SHORT).show();}}/*** 检查当前设备的网络连接状态,并返回连接状态和网络类型。* * @param context 上下文,提供了应用程序的环境信息。* @return 返回一个字符串,描述了当前网络的连接状态和类型。*/public static String checkNetworkConnectionAndGetType(Context context) {// 从系统服务中获取 ConnectivityManager 实例,用于管理网络连接。ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);// 获取当前活动的网络信息。NetworkInfo info = cm.getActiveNetworkInfo();if (info != null && info.isConnectedOrConnecting()) {// 如果网络已连接,返回网络类型名称,并且前面加上"连接"两个字。return "连接" + info.getTypeName();} else {// 如果网络未连接,返回"断开"。return "断开";}}
}
2.Mainactivity中应用NetworkChangeReceived

public class MainActivity extends AppCompatActivity {private NetworkChangeReceived networkChangeReceived;private static final int PERMISSION_REQUEST_CODE = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_NETWORK_STATE)!=PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, PERMISSION_REQUEST_CODE);}else {registerReceiver();}}@Overridepublic void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == PERMISSION_REQUEST_CODE){if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {registerReceiver();}else {Toast.makeText(this, "没有网络权限,无法检测网络状态", Toast.LENGTH_SHORT).show();}}}private void registerReceiver(){networkChangeReceived = new NetworkChangeReceived();IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);registerReceiver(networkChangeReceived,filter);}@Overrideprotected void onDestroy() {super.onDestroy();if (networkChangeReceived != null) {unregisterReceiver(networkChangeReceived);}}
}/*代码解释*//*** MainActivity 类,继承自 AppCompatActivity,是应用的主要活动入口点。*/
public class MainActivity extends AppCompatActivity {// 声明一个 NetworkChangeReceived 对象,用于接收网络状态变化的广播。private NetworkChangeReceived networkChangeReceived;// 定义一个常量,用于请求权限时的请求码。private static final int PERMISSION_REQUEST_CODE = 1;/*** 在 Activity 创建时调用。* * @param savedInstanceState 可能包含先前实例状态的 Bundle 对象。*/@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);EdgeToEdge.enable(this); // 这里假设 EdgeToEdge 是一个库的方法,用于设置全屏边缘到边缘的界面。setContentView(R.layout.activity_main); // 设置 Activity 的布局资源。// 检查是否已有访问网络状态的权限。if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {// 请求访问网络状态的权限。ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_NETWORK_STATE}, PERMISSION_REQUEST_CODE);} else {// 如果已经有权限,则注册网络状态变化的广播接收器。registerReceiver();}}/*** 当权限请求的结果返回时调用。* * @param requestCode 请求码,用于识别哪个权限请求的回调。* @param permissions 请求的权限数组。* @param grantResults 权限请求的结果数组。*/@Overridepublic void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == PERMISSION_REQUEST_CODE) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 如果权限被授予,注册网络状态变化的广播接收器。registerReceiver();} else {// 如果权限被拒绝,显示一个 Toast 提示用户。Toast.makeText(this, "没有网络权限,无法检测网络状态", Toast.LENGTH_SHORT).show();}}}/*** 注册网络状态变化的广播接收器。*/private void registerReceiver() {networkChangeReceived = new NetworkChangeReceived();IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);registerReceiver(networkChangeReceived, filter);}/*** 在 Activity 销毁时调用。*/@Overrideprotected void onDestroy() {super.onDestroy();if (networkChangeReceived != null) {// 在 Activity 销毁前,取消注册网络状态变化的广播接收器。unregisterReceiver(networkChangeReceived);}}
}

四、静态注册实现开机启动

        动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是它也存 在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写 在onCreate() 方法中的。这里我们准备让程序接收一条开机广播,当收到这条广播时就可以在onReceive() 方法里执 行相应的逻辑,从而实现开机启动的功能。可以使用Android Studio提供的快捷方式来创建一个 广播接收器,右击com.example.broadcasttest包→New→Other→Broadcast Receiver。

创建广播接收器的窗口

Exported 属性表示是否允许 这个广播接收器接收本程序以外的广播,Enabled 属性表示是否启用这个广播接收器。勾选这 两个属性,点击Finish完成创建。

自动新建一个类,并继承BroadcastReceiver

public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "My Receiver", Toast.LENGTH_LONG).show();}
}

五、AndroidManifest.xml文件中注册

        静态的广播接收器一定要在AndroidManifest.xml文件中注册才可以使用,不过由于我们是 使用Android Studio的快捷方式创建的广播接收器,因此注册这一步已经被自动完成了。打开 AndroidManifest.xml文件瞧一瞧,代码如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.MyApplication"tools:targetApi="31"><receiverandroid:name=".MyReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter></receiver><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest><!-- 代码解释 --><?xml version="1.0" encoding="utf-8"?>
<!-- 指定文档的版本和编码方式 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><!-- 声明命名空间,定义了 Android 和工具属性的前缀 --><!-- 声明应用需要的权限 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!-- 允许应用访问网络状态 --><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><!-- 允许应用接收设备启动完成的广播 --><applicationandroid:allowBackup="true"<!-- 应用的数据是否允许被备份 -->android:dataExtractionRules="@xml/data_extraction_rules"<!-- 数据提取规则,定义哪些数据可以被提取 -->android:fullBackupContent="@xml/backup_rules"<!-- 完整备份内容规则,定义哪些数据应该包含在完整备份中 -->android:icon="@mipmap/ic_launcher"<!-- 应用图标资源的引用 -->android:label="@string/app_name"<!-- 应用的显示名称 -->android:roundIcon="@mipmap/ic_launcher_round"<!-- 圆形应用图标资源的引用,适用于圆形图标显示的场景 -->android:supportsRtl="true"<!-- 是否支持从右到左的语言布局方向 -->android:theme="@style/Theme.MyApplication"<!-- 应用主题的样式引用 -->tools:targetApi="31"><!-- 工具属性,指定应用的目标 API 级别 --><!-- 定义一个广播接收器 --><receiverandroid:name=".MyReceiver"android:enabled="true"<!-- 是否启用该接收器 -->android:exported="true"><!-- 是否允许其他应用发送广播到该接收器 --><intent-filter><!-- 定义接收器能够接收的广播类型 --><action android:name="android.intent.action.BOOT_COMPLETED"/><!-- 接收设备启动完成的广播 --></intent-filter></receiver><!-- 定义一个活动 --><activityandroid:name=".MainActivity"android:exported="true"><!-- 活动的类名和是否允许外部应用启动 --><intent-filter><!-- 定义活动能够响应的意图类型 --><action android:name="android.intent.action.MAIN" /><!-- 活动是应用的入口点 --><category android:name="android.intent.category.LAUNCHER" /><!-- 活动属于 Launcher 类别,意味着它会出现在应用启动器中 --></intent-filter></activity></application>
</manifest>

        由于Android系统启动完成后会发出一条值为android.intent.action.BOOT_COMPLETED 的广播,因此我们在 标签里添加了相应的action。另外,监听系统开机广播 也是需要声明权限的,可以看到,我们使用 标签又加入了一 条android.permission.RECEIVE_BOOT_COMPLETED 权限。目前为止,我们在广播接收器的onReceive() 方法中都只是简单地使用Toast提示了一段文 本信息,当你真正在项目中使用到它的时候,就可以在里面编写自己的逻辑。需要注意的是, 不要在onReceive() 方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中 是不允许开启线程的,当onReceive() 方法运行了较长时间而没有结束时,程序就会报错。 因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者 启动一个服务等,

相关文章:

Android广播机制

简介 某个网络的IP范围是192.168.0.XXX&#xff0c;子网 掩码是255.255.255.0&#xff0c;那么这个网络的广播地址就是192.168.0.255。广播数据包会被发送到同一 网络上的所有端口&#xff0c;这样在该网络中的每台主机都将会收到这条广播。为了便于进行系统级别的消息通知&…...

SQL FOREIGN KEY

SQL FOREIGN KEY 简介 SQL(Structured Query Language)是用于管理关系数据库管理系统(RDBMS)的标准编程语言。在SQL中,FOREIGN KEY是一个重要的概念,用于建立和维护数据库中不同表之间的关系。本文将详细介绍SQL FOREIGN KEY的概念、用途、以及如何在SQL中实现和使用FO…...

绘唐3最新版本哪里下载

绘唐3最新版本哪里下载 绘唐最新版本下载地址 推文视频创作设计是一种通过视频和文字的形式来进行推广的方式&#xff0c;可以通过一些专业的工具来进行制作。 以下是一些常用的小说推文视频创作设计工具&#xff1a; 视频剪辑软件&#xff1a;如Adobe Premiere Pro、Fina…...

[ES6] 箭头函数

JavaScript 是一种广泛使用的编程语言&#xff0c;随着其发展和演变&#xff0c;引入了很多新的特性来提高代码的可读性和开发效率。其中一个重要的特性就是 ES6&#xff08;ECMAScript 2015&#xff09;中引入的箭头函数&#xff08;Arrow Function&#xff09;。箭头函数不仅…...

BiLSTM模型实现

# 本段代码构建类BiLSTM, 完成初始化和网络结构的搭建 # 总共3层: 词嵌入层, 双向LSTM层, 全连接线性层 # 本段代码构建类BiLSTM, 完成初始化和网络结构的搭建 # 总共3层: 词嵌入层, 双向LSTM层, 全连接线性层 import torch import torch.nn as nn# 本函数实现将中文文本映射为…...

linux内核源码学习所需基础

1.面向对象的思想&#xff0c;尤其是oopc的实现方式。 2.设计模式。 这两点需要内核源码学习者不仅要会c和汇编&#xff0c;还要接触一门面向对象的语言&#xff0c;比如c&#xff0b;&#xff0b;/java/python等等任意一门都行&#xff0c;起码要了解面向对象的思想。 另外li…...

Java并发编程-AQS详解及案例实战(上篇)

文章目录 AQS概述AQS 的核心概念AQS 的工作原理AQS 的灵活性使用场景使用指南使用示例AQS的本质:为啥叫做异步队列同步器AQS的核心机制“异步队列”的含义“同步器”的含义总结加锁失败的时候如何借助AQS异步入队阻塞等待AQS的锁队列加锁失败时的处理流程异步入队的机制总结Ree…...

第11章 规划过程组(二)(11.8排列活动顺序)

第11章 规划过程组&#xff08;二&#xff09;11.8排列活动顺序&#xff0c;在第三版教材第391页&#xff1b; 文字图片音频方式 第一个知识点&#xff1a;主要输出 1、项目进度网络图 如图11-20 项目进度网络图示例 带有多个紧前活动的活动代表路径汇聚&#xff0c;而带有…...

DP学习——观察者模式

学而时习之&#xff0c;温故而知新。 敌人出招&#xff08;使用场景&#xff09; 多个对象依赖一个对象的状态改变&#xff0c;当业务中有这样的关系时你出什么招&#xff1f; 你出招 这个时候就要用观察者模式这招了&#xff01; 2个角色 分为啥主题和观察者角色。 我觉…...

如何利用GPT-4o生成有趣的梗图

文章目录 如何利用GPT-4o生成有趣的梗图一、引言二、使用GPT-4o生成梗图1. 提供主题2. 调用工具3. 获取图片实际案例输入输出 三、更多功能1. 创意和灵感2. 梗图知识 四、总结 如何利用GPT-4o生成有趣的梗图 梗图&#xff0c;作为互联网文化的一部分&#xff0c;已经成为了我们…...

深入理解 KVO

在 iOS 中&#xff0c;KVO&#xff08;Key-Value Observing&#xff09;是一个强大的观察机制&#xff0c;它的底层实现相对复杂。KVO 利用 Objective-C 的动态特性&#xff0c;为对象的属性提供观察能力。 KVO 的底层实现 1. 动态子类化 当一个对象的属性被添加观察者时&am…...

当需要对大量数据进行排序操作时,怎样优化内存使用和性能?

文章目录 一、选择合适的排序算法1. 快速排序2. 归并排序3. 堆排序 二、数据结构优化1. 使用索引2. 压缩数据3. 分块排序 三、外部排序1. 多路归并排序 四、利用多核和并行计算1. 多线程排序2. 使用并行流 五、性能调优技巧1. 避免不必要的内存复制2. 缓存友好性3. 基准测试和性…...

kubernetes集群部署:node节点部署和cri-docker运行时安装(四)

安装前准备 同《kubernetes集群部署&#xff1a;环境准备及master节点部署&#xff08;二&#xff09;》 安装cri-docker 在 Kubernetes 1.20 版本之前&#xff0c;Docker 是 Kubernetes 默认的容器运行时。然而&#xff0c;Kubernetes 社区决定在 Kubernetes 1.20 及以后的…...

第五十章 Web Service URL 汇总

文章目录 第五十章 Web Service URL 汇总Web 服务 URLWeb 服务的端点WSDL 使用受密码保护的 WSDL URL 第五十章 Web Service URL 汇总 本主题总结了与 IRIS 数据平台 Web 服务相关的 URL。 Web 服务 URL 与 IRIS Web 服务相关的 URL 如下&#xff1a; Web 服务的端点 http…...

动态白色小幽灵404网站源码

动态白色小幽灵404网站源码&#xff0c;页面时单页HTML源码&#xff0c;将代码放到空白的html里面&#xff0c;鼠标双击html即可查看效果&#xff0c;或者上传到服务器&#xff0c;错误页重定向这个界面即可&#xff0c;喜欢的朋友可以拿去使用 <!DOCTYPE html> <ht…...

axios的使用,处理请求和响应,axios拦截器

1、axios官网 https://www.axios-http.cn/docs/interceptors 2、安装 npm install axios 3、在onMouunted钩子函数中使用axios来发送请求&#xff0c;接受响应 4.出现的问题&#xff1a; &#xff08;1&#xff09; 但是如果发送请求请求时间过长&#xff0c;回出现请求待处…...

visual studio 2017增加.cu文件

右击项目名称&#xff0c;选择生成依赖项>生成自定义把CUDA11.3target勾选上&#xff1b; 把带有cuda代码的.cpp文件和.cu文件右击属性>项类型>选择CUDA C/C 右击项目名称&#xff0c;C/C>命令行添加/D _CRT_SECURE_NO_WARNINGS&#xff1b; 选择CUDA C/C>命…...

linux 管道符 |

在Linux中&#xff0c;管道符&#xff08;|&#xff09;是一个非常重要的概念&#xff0c;它允许你将一个命令的输出作为另一个命令的输入。这种机制使得Linux命令可以非常灵活地进行组合&#xff0c;从而执行复杂的任务。 管道符的基本用法 假设你有两个命令&#xff1a;com…...

Android - SIP 协议

SIP 代表(会话发起协议)。 它是一种协议&#xff0c;可让应用程序轻松设置呼出和呼入语音呼叫&#xff0c;而无需直接管理会话、传输级通信或音频记录或回放。 SIP 应用程序 SIP 的一些常见应用是。 视频会议即时消息 开发要求 以下是开发 SIP 应用程序的要求 − Android 操作系…...

Python结合MobileNetV2:图像识别分类系统实战

一、目录 算法模型介绍模型使用训练模型评估项目扩展 二、算法模型介绍 图像识别是计算机视觉领域的重要研究方向&#xff0c;它在人脸识别、物体检测、图像分类等领域有着广泛的应用。随着移动设备的普及和计算资源的限制&#xff0c;设计高效的图像识别算法变得尤为重要。…...

【】AI八股-神经网络相关

Deep-Learning-Interview-Book/docs/深度学习.md at master amusi/Deep-Learning-Interview-Book GitHub 网上相关总结&#xff1a; 小菜鸡写一写基础深度学习的问题&#xff08;复制大佬的&#xff0c;自己复习用&#xff09; - 知乎 (zhihu.com) CV面试问题准备持续更新贴 …...

NodeJs的安装与环境变量配置

Node.js的环境变量配置主要涉及设置Node.js的安装路径、npm&#xff08;Node Package Manager&#xff09;的全局模块安装路径和缓存路径&#xff0c;以及可能需要的国内镜像源配置。以下是详细的配置步骤&#xff1a; 一、安装Node.js 下载Node.js安装包&#xff1a; 访问Nod…...

进程输入输出及终端属性学习

进程的标准输入输出 当主进程fork或exec子进程&#xff0c;文件描述符被继承&#xff0c;因此0,1,2句柄也被继承&#xff0c;从而使得telnet等服务&#xff0c;可以做到间接调用别的shell或程序。比如如果是远程登录使用的zsh&#xff0c;那么其会重定向到相应的pts $ ps|gre…...

关于redis集群和事务

最近为了核算项目的两个架构指标&#xff08;可用性和伸缩性&#xff09;&#xff0c;需要对项目中使用的Redis数据库的集群部署进行一定程度的了解&#xff0c;当然顺便再学习一遍它的事务细节。 既然我在上面把Redis称之为数据库&#xff0c;那么在我们目前的项目里&#xf…...

ctfshow-web入门-文件包含(web88、web116、web117)

目录 1、web88 2、web116 3、web117 1、web88 没有过滤冒号 : &#xff0c;可以使用 data 协议&#xff0c;但是过滤了括号和等号&#xff0c;因此需要编码绕过一下。 这里有点问题&#xff0c;我 (ls) 后加上分号发现不行&#xff0c;可能是编码结果有加号&#xff0c;题目…...

My sql 安装,环境搭建

以下以MySQL 8.0.36为例。 一、下载软件 1.下载地址官网&#xff1a;https://www.mysql.com 2. 打开官网&#xff0c;点击DOWNLOADS 然后&#xff0c;点击 MySQL Community(GPL) Downloads 3. 点击 MySQL Installer for Windows 4.点击Archives选择合适版本 5.选择后下载…...

JVM原理(二十):JVM虚拟机内存的三特性详解

1. 原子性、可进行、有序性 1.1. 原子性 Java内存模型围绕着在并发过程中如何处理原子性、可见性和有序性这三个特征来建立的。 Java内存模型来直接保证的原子性变量操作包括read、load、assign、use、store和write这六个。我们大致可以认为&#xff0c;基本数据类型的访问、…...

Flink 窗口触发器(Trigger)(二)

Flink 窗口触发器(Trigger)(一) Flink 窗口触发器(Trigger)(二) Apache Flink 是一个开源流处理框架&#xff0c;用于处理无界和有界数据流。在 Flink 的时间窗口操作中&#xff0c;触发器&#xff08;Trigger&#xff09;是一个非常重要的概念&#xff0c;它决定了窗口何时应…...

CH12_函数和事件

第12章&#xff1a;Javascript的函数和事件 本章目标 函数的概念掌握常用的系统函数掌握类型转换掌握Javascript的常用事件 课程回顾 Javascript中的循环有那些&#xff1f;Javascript中的各个循环特点是什么&#xff1f;Javascript中的各个循环语法分别是什么&#xff1f;…...

Android- Framework 非Root权限实现修改hosts

一、背景 修改system/etc/hosts&#xff0c;需要具备root权限&#xff0c;而且remount后&#xff0c;才能修改&#xff0c;本文介绍非root状态下修改system/etc/hosts方案。 环境&#xff1a;高通 Android 13 二、方案 非root&#xff0c;system/etc/hosts只有只读权限&…...

mac安装达梦数据库

参考&#xff1a;mac安装达梦数据库​​​​​​ 实践如下&#xff1a; 1、下载达梦Docker镜像文件 同参考链接 2、导入镜像 镜像可以随便放在某个目录&#xff0c;相当于安装包&#xff0c;导入后就没有作用了。 查找达梦镜像名称&#xff1a;dm8_20240613_rev229704_x86…...

14-41 剑和诗人15 - RLAIF 大模型语言强化培训

​​​​​​ 介绍 大型语言模型 (LLM) 在自然语言理解和生成方面表现出了巨大的能力。然而&#xff0c;这些模型仍然存在严重的缺陷&#xff0c;例如输出不可靠、推理能力有限以及缺乏一致的个性或价值观一致性。 为了解决这些限制&#xff0c;研究人员采用了一种名为“人工…...

每日一题~oj(贪心)

对于位置 i来说&#xff0c;如果 不选她&#xff0c;那她的贡献是 vali-1 *2&#xff0c;如果选他 &#xff0c;那么她的贡献是 ai. 每一个数的贡献 是基于前一个数的贡献 来计算的。只要保证这个数的前一个数的贡献是最优的&#xff0c;那么以此类推下去&#xff0c;整体的val…...

成人高考报名条件及收费标准详解

成人高考报名条件及收费标准详解 您想通过成人高考改变自己的命运&#xff0c;但不知道报名条件和收费标准&#xff1f;本文将为您详细介绍成人高考报名条件和收费标准&#xff0c;并为您提供专业的成人教育服务。 深圳成人高考www.shenzhixun.com 成人高考报名条件 成人高考…...

openmetadata1.3.1 自定义连接器 开发教程

openmetadata自定义连接器开发教程 一、开发通用自定义连接器教程 官网教程链接&#xff1a; 1.https://docs.open-metadata.org/v1.3.x/connectors/custom-connectors 2.https://github.com/open-metadata/openmetadata-demo/tree/main/custom-connector &#xff08;一&…...

PostgreSQL 如何优化存储过程的执行效率?

文章目录 一、查询优化1. 正确使用索引2. 避免不必要的全表扫描3. 使用合适的连接方式4. 优化子查询 二、参数传递1. 避免传递大对象2. 参数类型匹配 三、减少数据量处理1. 限制返回结果集2. 提前筛选数据 四、优化逻辑结构1. 分解复杂的存储过程2. 避免过度使用游标 五、事务处…...

普中51单片机:数码管显示原理与实现详解(四)

文章目录 引言数码管的结构数码管的工作原理静态数码管电路图开发板IO连接图代码演示 动态数码管实现步骤数码管驱动方式电路图开发板IO连接图真值表代码演示1代码演示2代码演示3 引言 数码管&#xff08;Seven-Segment Display&#xff09;是一种常见的显示设备&#xff0c;广…...

web缓存代理服务器

一、web缓存代理 web代理的工作机制 代理服务器是一个位于客户端和原始&#xff08;资源&#xff09;服务器之间的服务器&#xff0c;为了从原始服务器取得内容&#xff0c;客户端向代理服务器发送一个请求&#xff0c;并指定目标原始服务器&#xff0c;然后代理服务器向原始…...

容器:queue(队列)

以下是关于queue容器的总结 1、构造函数&#xff1a;queue [queueName] 2、添加、删除元素: push() 、pop() 3、获取队头/队尾元素&#xff1a;front()、back() 4、获取栈的大小&#xff1a;size() 5、判断栈是否为空&#xff1a;empty() #include <iostream> #include …...

探索 WebKit 的后台同步新纪元:Web Periodic Background Synchronization 深度解析

探索 WebKit 的后台同步新纪元&#xff1a;Web Periodic Background Synchronization 深度解析 随着 Web 应用逐渐成为我们日常生活中不可或缺的一部分&#xff0c;用户对应用的响应速度和可靠性有了更高的期待。Web Periodic Background Synchronization API&#xff08;周期…...

ctfshow web入门 web338--web344

web338 原型链污染 comman.js module.exports {copy:copy };function copy(object1, object2){for (let key in object2) {if (key in object2 && key in object1) {copy(object1[key], object2[key])} else {object1[key] object2[key]}}}login.js var express …...

mupdf加载PDF显示中文乱码

现象 加载PDF显示乱码,提示非嵌入字体 non-embedded font using identity encoding调式 在pdf-font.c中加载字体 调试源码发现pdf文档的字体名字居然是GBK&#xff0c;估计又是哪个windows下写的pdf生成工具生成pdf 字体方法&#xff1a; static pdf_font_desc * load_cid…...

常用的限流工具Guava RateLimiter 或Redisson RRateLimiter

在分布式系统和高并发场景中&#xff0c;限流是一个非常常见且重要的需求。以下是一些常用的限流工具和库&#xff0c;包括它们的特点和使用场景&#xff1a; 1. Guava RateLimiter Google 的 Guava 库中的 RateLimiter 是一个简单且高效的限流工具&#xff0c;适用于单节点应…...

卷积神经网络(CNN)和循环神经网络(RNN) 的区别与联系

卷积神经网络&#xff08;CNN&#xff09;和循环神经网络&#xff08;RNN&#xff09;是两种广泛应用于深度学习的神经网络架构&#xff0c;它们在设计理念和应用领域上有显著区别&#xff0c;但也存在一些联系。 ### 卷积神经网络&#xff08;CNN&#xff09; #### 主要特点…...

Unity【入门】场景切换和游戏退出及准备

1、必备知识点场景切换和游戏退出 文章目录 1、必备知识点场景切换和游戏退出1、场景切换2、鼠标隐藏锁定相关3、随机数和自带委托4、模型资源的导入1、模型由什么构成2、Unity支持的模型格式3、如何指导美术同学导出模型4、学习阶段在哪里获取模型资源 2、小项目准备工作需求分…...

Python 函数递归

以下是一个使用递归计算阶乘的 Python 函数示例 &#xff1a; 应用场景&#xff1a; 1. 动态规划问题&#xff1a;在一些需要逐步求解子问题并利用其结果的动态规划场景中&#xff0c;递归可以帮助直观地表达问题的分解和求解过程。 2. 遍历具有递归结构的数据&#xff1a;如递…...

MyBatis(27)如何配置 MyBatis 实现打印可执行的 SQL 语句

在开发过程中&#xff0c;打印可执行的SQL语句对于调试和性能优化是非常有帮助的。MyBatis提供了几种方式来实现SQL语句的打印。 1. 使用日志框架 MyBatis可以通过配置其内部使用的日志框架&#xff08;如Log4j、Logback等&#xff09;来打印SQL语句。这是最常用的方法。 Lo…...

3.js - 裁剪平面(clipIntersection:交集、并集)

看图 代码 // ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import …...

在5G/6G应用中实现高性能放大器的建模挑战

来源&#xff1a;Modelling Challenges for Enabling High Performance Amplifiers in 5G/6G Applications {第28届“集成电路和系统的混合设计”(Mixed Design of Integrated Circuits and Systems)国际会议论文集&#xff0c;2021年6月24日至26日&#xff0c;波兰洛迪} 本文讨…...

Perl 数据类型

Perl 数据类型 Perl 是一种功能丰富的编程语言&#xff0c;广泛应用于系统管理、网络编程、GUI 开发等领域。在 Perl 中&#xff0c;数据类型是编程的基础&#xff0c;决定了变量存储信息的方式以及可以对这些信息执行的操作。本文将详细介绍 Perl 中的主要数据类型&#xff0…...