Android Jetpack组件之WorkManager高级概念介绍与使用(三)
一、介绍
通过前面两篇,我们基本掌握了组件的workmanager的接入,以及api的使用等。但是一个框架如果运用在复杂的项目中,肯定需要有其他额外的支持,介绍来我们将会介绍高级概念,以及对前面的知识点进行回顾与拓展。
高级概念
一、配置和初始化
默认情况下,当您的应用启动时,WorkManager 使用适合大多数应用的合理选项自动进行配置。如果您需要进一步控制 WorkManager 管理和调度工作的方式,可以通过自行初始化 WorkManager 来自定义 WorkManager 配置
移除默认初始化程序
如需提供自己的配置,必须先移除默认初始化程序。为此,请使用合并规则 tools:node="remove"
从 WorkManager 2.6 开始,应用启动功能便已在 WorkManager 内部使用。如需提供自定义初始化程序,您需要移除 androidx.startup 节点
如果您不在应用中使用应用启动功能,则可以将其彻底移除。
<!-- If you want to disable android.startup completely. --><providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"tools:node="remove"></provider>
否则,仅移除 WorkManagerInitializer 节点即可。
<providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"android:exported="false"tools:node="merge"><!-- If you are using androidx.startup to initialize other components --><meta-dataandroid:name="androidx.work.WorkManagerInitializer"android:value="androidx.startup"tools:node="remove" /></provider>
如果您使用的 WorkManager 是 2.6 之前的版本,请改为移除 workmanager-init:
<providerandroid:name="androidx.work.impl.WorkManagerInitializer"android:authorities="${applicationId}.workmanager-init"tools:node="remove" />
二、实现 Configuration.Provider
让项目 Application 类实现 Configuration.Provider 接口,并提供您自己的 Configuration.Provider.getWorkManagerConfiguration() 实现。当您需要使用 WorkManager 时,请务必调用方法 WorkManager.getInstance(Context)。WorkManager 会调用应用的自定义 getWorkManagerConfiguration() 方法来发现其 Configuration
public class MyApp extends Application implements Configuration.Provider {@NonNull@Overridepublic Configuration getWorkManagerConfiguration() {Configuration.Builder builder= new Configuration.Builder();builder.setMinimumLoggingLevel(android.util.Log.DEBUG);return builder.build();}
}
三、WorkManager 2.1.0 之前版本的自定义初始化
在您的应用启动时,WorkManager 会使用自定义 ContentProvider 自行初始化。此代码位于内部类 androidx.work.impl.WorkManagerInitializer 中,并使用默认 Configuration。自动使用默认初始化程序(除非明确停用它)。默认初始化程序适合大多数应用
自定义初始化:
val myConfig = Configuration.Builder().setMinimumLoggingLevel(android.util.Log.INFO).build()// initialize WorkManager
WorkManager.initialize(this, myConfig)
四、WorkManager中的线程处理
在 WorkManager 使用入门中,我们提到 WorkManager 可以代表您异步执行后台工作。该基本实现可满足大多数应用的需求。关于更高级的用例(例如正确处理正在停止的工作),您应了解 WorkManager 中的线程处理和并发机制。
WorkManager 提供了四种不同类型的工作基元:
- Worker 是最简单的实现,我们已在前面几节进行了介绍。WorkManager 会在后台线程中自动运行该基元(您可以将它替换掉)。请参阅工作器中的线程处理,详细了解
Worker实例中的线程处理。 - CoroutineWorker 是为 Kotlin 用户建议的实现。
CoroutineWorker实例公开了后台工作的一个挂起函数。默认情况下,这些实例运行默认的Dispatcher,但您可以进行自定义。请参阅 CoroutineWorker 中的线程处理,详细了解CoroutineWorker实例中的线程处理。 - RxWorker 是为 RxJava 用户建议的实现。如果您有很多现有异步代码是用 RxJava 建模的,则应使用 RxWorker。与所有 RxJava 概念一样,您可以自由选择所需的线程处理策略。请参阅 RxWorker 中的线程处理,详细了解
RxWorker实例中的线程处理。 - ListenableWorker 是
Worker、CoroutineWorker和RxWorker的基类。这个类专为需要与基于回调的异步 API(例如FusedLocationProviderClient)进行交互并且不使用 RxJava 的 Java 开发者而设计。请参阅 ListenableWorker 中的线程处理,详细了解ListenableWorker实例中的线程处理。
五、工作器中的线程处理
当您使用 Worker 时,WorkManager 会自动在后台线程中调用 Worker.doWork()。该后台线程来自于 WorkManager 的 Configuration 中指定的 Executor。默认情况下,WorkManager 会为您设置 Executor,但您也可以自己进行自定义。例如,您可以在应用中共享现有的后台 Executor,也可以创建单线程 Executor 以确保所有后台工作都按顺序执行,甚至可以指定一个自定义 Executor
在手动配置 WorkManager 时,您可以按以下方式指定 Executor:
fun initConfig()
{WorkManager.initialize(application,Configuration.Builder()// Uses a fixed thread pool of size 8 threads..setExecutor(Executors.newFixedThreadPool(8)).build()) }
接下来我们会执行一个64次的重复,需要重写work
class MyWork(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {var count = 1;override fun doWork(): Result {
// TODO("Not yet implemented")repeat(64) {Log.e("Mywork", "" + count++)return Result.success()}return Result.success()}
}
只需要在doWork中,进行repeat的即可。填入重复项。
repeat方法:
@kotlin.internal.InlineOnly
public inline fun repeat(times: Int, action: (Int) -> Unit) {contract { callsInPlace(action) }for (index in 0 until times) {action(index)}
}
就是一个不停调用action的执行方法。
注意:
第一点:
Worker.doWork() 是同步调用 - 您应以阻塞方式完成整个后台工作,并在方法退出时完成工作。如果您在 doWork() 中调用异步 API 并返回 Result,那么回调可能无法正常运行。如果您遇到这种情况,请考虑使用 ListenableWorker
第二点:
如果当前正在运行的 Worker 因任何原因而停止,它就会收到对 Worker.onStopped() 的调用。在必要的情况下,只需替换此方法或调用 Worker.isStopped(),即可对代码进行检查点处理并释放资源。当上述示例中的 Worker 被停止时,内容的下载可能才完成了一半;但即使该工作器被停止,下载也会继续。
如果想同步,在执行时,需要对isStop进行拦截
override fun doWork(): Result {
// TODO("Not yet implemented")repeat(64) {if (!isStopped) {Log.e("Mywork", "" + count++)}}return Result.success()}
六、CoroutineWorker 中的线程处理
WorkManager 为协程提供了一流的支持。如要开始使用,请将 work-runtime-ktx 包含到您的 gradle 文件中。继承 CoroutineWorker,包含 doWork() 的挂起版本
class MyCoroutineWorker(appContext: Context,params: WorkerParameters
) : CoroutineWorker(appContext, params) {override suspend fun doWork(): Result {
}
}
CoroutineWorker.doWork() 是一个“挂起”函数。不同于 Worker,不会在 Configuration 中指定的 Executor 中运行,而是默认为 Dispatchers.Default。
您可以提供自己的 CoroutineContext 来自定义这个行为。在上面的示例中,您可能希望在 Dispatchers.Main上完成此操作。
override suspend fun doWork(): Result {withContext(Dispatchers.Main){}return Result.Success.success()}
CoroutineDispatcher提供了如下:
Dispatchers.Default Dispatchers.IO Dispatchers.Main Dispatchers.Unconfined
CoroutineWorker 通过取消协程并传播取消信号来自动处理停工情况,无需执行任何特殊操作来处理停工情况。
七、在其他进程中运行 CoroutineWorker
使用 RemoteCoroutineWorker(ListenableWorker 的实现)将工作器绑定到特定进程。
RemoteCoroutineWorker 会使用您在构建工作请求时于输入数据中提供的两个额外参数绑定到特定进程:ARGUMENT_CLASS_NAME 和 ARGUMENT_PACKAGE_NAME
fun BindWorkRequest() :WorkRequest{val PACKAGE_NAME = packageNameval serviceName = RemoteWorkerService::class.java.nameval componentName = ComponentName(PACKAGE_NAME, serviceName)val data: Data = Data.Builder().putString(RemoteListenableWorker.ARGUMENT_PACKAGE_NAME, componentName.packageName).putString(RemoteListenableWorker.ARGUMENT_CLASS_NAME, componentName.className).build()return OneTimeWorkRequest.Builder(MyCoroutineWorker::class.java).setInputData(data).build()}
还需要在 AndroidManifest.xml 文件中添加服务定义:
<serviceandroid:name="androidx.work.multiprocess.RemoteWorkerService"android:exported="false"android:process=":worker1" /><serviceandroid:name=".RemoteWorkerService2"android:exported="false"android:process=":worker2" />
RemoteWorkerService2是一个空service,需要我们自己去创建。
八、RxWorker 中的线程处理
在 WorkManager 与 RxJava 之间提供互操作性。如需开始使用这种互操作性,除了在您的 gradle 文件中包含 work-runtime 之外,还应包含 work-rxjava3 依赖项。而且还有一个支持 rxjava2 的 work-rxjava2 依赖项,您可以根据情况使用。
需要定义自己的 RxWorker,替换 RxWorker.createWork() 方法以返回 Single<Result>,用于表示代码执行的 Result。
class MyRxWork( appContext:Context, workerParams:WorkerParameters ) : RxWorker(appContext, workerParams) {override fun createWork(): Single<Result> {return Observable.range(0,100).toList().map { Result.Success }}}
注意:
RxWorker.createWork() 在主线程上调用,但默认情况下会在后台线程上订阅返回值。您可以替换 RxWorker.getBackgroundScheduler() 来更改订阅线程。
当 RxWorker 为 onStopped() 时,系统会处理订阅,因此您无需以任何特殊方式处理停工情况。
override fun getBackgroundScheduler(): Scheduler {return super.getBackgroundScheduler()}
九、ListenableWorker 中的线程处理
在某些情况下,需要提供自定义线程处理策略,需要处理基于回调的异步操作。在这种情况下,不能只依靠 Worker 来完成操作,因为它无法以阻塞方式完成这项工作。WorkManager 通过 ListenableWorker 支持该用例。ListenableWorker 是最基本的工作器 API;Worker、CoroutineWorker 和 RxWorker 都是从这个类衍生而来的。ListenableWorker 只会发出信号以表明应该开始和停止工作,而线程处理则完全交您决定。开始工作信号在主线程上调用,因此请务必手动转到您选择的后台线程。
抽象方法 ListenableWorker.startWork() 会返回一个将使用操作的 Result 设置的 ListenableFuture。ListenableFuture 是一个轻量级接口:它是一个 Future,用于提供附加监听器和传播异常的功能。在 startWork 方法中,应该返回 ListenableFuture,完成操作后,您需要使用操作的 Result 设置这个返回结果
- 如果您使用的是 Guava,请使用
ListeningExecutorService。 - 否则,请将 councurrent-futures 包含到您的 gradle 文件中并使用 CallbackToFutureAdapter
使用CallBackToFutureAdapter,需要引入依赖
implementation("androidx.concurrent:concurrent-futures-ktx:1.1.0")
implementation("androidx.concurrent:concurrent-futures:1.1.0")
class MyListenableWorker(context: Context,params: WorkerParameters
) : ListenableWorker(context, params) {override fun startWork(): ListenableFuture<Result> {return CallbackToFutureAdapter.getFuture { completer ->val callback = object : Callback {var successes = 0override fun onFailure(call: Call, e: IOException) {completer.setException(e)}override fun onResponse(call: Call, response: Response) {successes++if (successes == 100) {completer.set(Result.success())}}}repeat(100) {Log("info","infosssss")}callback}}
}
如果您的工作停止会发生什么?如果预计工作会停止,则始终会取消 ListenableWorker 的 ListenableFuture。通过使用 CallbackToFutureAdapter,您只需添加一个取消监听器即可
completer.addCancellationListener(Runnable runable,Executor executor)
十、在其他进程中运行 ListenableWorker
和CoroutineWorker 用法一样,因为CoroutineWorker 也是ListenableWorker的派生类。可参考上面资料
十一、长时间运行的 worker
WorkManager 为长时间运行的 worker 提供内置支持。在这种情况下,WorkManager 可以向操作系统提供一个信号,指示在此项工作执行期间应尽可能让进程保持活跃状态。这些 worker 可以运行超过 10 分钟。
在后台,WorkManager 会代表您管理和运行前台服务以执行 WorkRequest,同时还会显示可配置的通知。
ListenableWorker 现在支持 setForegroundAsync() API,而 CoroutineWorker 则支持挂起 setForeground() API。这些 API 允许开发者指定此 WorkRequest 是“重要的”(从用户的角度来看)或“长时间运行的”任务。
从 2.3.0-alpha03 开始,WorkManager 还允许您创建 PendingIntent,此 Intent 可用于取消 worker,而不必使用 createCancelPendingIntent() API 注册新的 Android 组件。此方法与 setForegroundAsync() 或 setForeground() API 一起使用时特别有用,可用于添加一个取消 Worker 的通知操作。
步骤:
1、我们需要定义一个CoroutineWorker类
2、早doWork()方法中,调用=setForeground(info:ForegroundInfo)
3、这个ForegroundInfo需要我们去构建
private fun createForegroundInfo(progress: String): ForegroundInfo {val id = applicationContext.getString(R.string.notification_channel_id)val title = applicationContext.getString(R.string.notification_title)val cancel = applicationContext.getString(R.string.cancel_download)// This PendingIntent can be used to cancel the workerval intent = WorkManager.getInstance(applicationContext).createCancelPendingIntent(getId())// Create a Notification channel if necessaryif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {createChannel()}val notification = NotificationCompat.Builder(applicationContext, id).setContentTitle(title).setTicker(title).setContentText(progress).setSmallIcon(R.drawable.ic_work_notification).setOngoing(true)// Add the cancel action to the notification which can// be used to cancel the worker.addAction(android.R.drawable.ic_delete, cancel, intent).build()val notificationId= Random.nextInt(1,Int.MAX_VALUE)return ForegroundInfo(notificationId, notification)}@RequiresApi(Build.VERSION_CODES.O)private fun createChannel() {// Create a Notification channel}
ForegroundInfo是一个持有通知对象的前景info。
十二、将前台服务类型添加到长时间运行的 worker
如果您的应用以 API 级别 29或更高版本为目标平台,且包含需要位置信息访问权限的长时间运行的 worker,请指明该 worker 使用 location 的前台服务类型。此外,如果您的应用以 Android API 级别 30或更高版本为目标平台,且包含需要访问摄像头或麦克风的长时间运行的 worker,请分别声明 camera 或 microphone 前台服务类型。
如需添加这些前台服务类型,在应用清单中声明前台服务类型
<serviceandroid:name="androidx.work.impl.foreground.SystemForegroundService"android:foregroundServiceType="location|microphone"tools:node="merge" />
在运行时指定前台服务类型
当您调用 setForeground() 或 setForegroundAsync() 时,请指定前台服务类型 FOREGROUND_SERVICE_TYPE_LOCATION、FOREGROUND_SERVICE_TYPE_CAMERA 或 FOREGROUND_SERVICE_TYPE_MICROPHONE
创建:ForegroundInfo
ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION or
FOREGROUND_SERVICE_TYPE_MICROPHONE)
十三、总结
通过以上三篇文章,已完全分析完WorkManager的工作机制,以及场景的使用。我们在自己的项目中,或者需求中,可以运用workmanager来完成一些复杂的工作,提高我们的应用交互的便捷性。
相关文章:
Android Jetpack组件之WorkManager高级概念介绍与使用(三)
一、介绍 通过前面两篇,我们基本掌握了组件的workmanager的接入,以及api的使用等。但是一个框架如果运用在复杂的项目中,肯定需要有其他额外的支持,介绍来我们将会介绍高级概念,以及对前面的知识点进行回顾与拓展。 高…...
Spring框架中用到的设计模式(都用到了哪些设计模式?)
文章目录简单工厂模式:工厂模式:单例模式:原型模式:迭代器模式:代理模式:适配器模式:观察者模式:模板模式:责任链模式:这是一道相对有难度的题目,…...
Python中的类和对象(4)
1. 构造函数 (_ init _(self[,……])) 在类中定义 _init _() 方法,可以实现在实例化对象的时候进行个性化定制: >>> class C: ... def __init__(self, x, y): ... self.x x ... self.y y ... …...
window11 安装node及配置环境变量
一、安装环境 本教程演示的环境: 系统:win 11 64位 node.js下载地址: http://nodejs.cn/ node.js版本:长期支持版本(本教程基于16.15.0) 点击选中图标下载到电脑本地即可。 二、安装步骤 1、双击安装包,一…...
腾讯云服务器选购新手教程(新版流程超级详细)
腾讯云服务器购买有两个入口,一个是直接在秒杀活动上购买云服务器,价格便宜,2核2G4M轻量服务器,2核4G6M服务器、4核8G10M服务器,活动上购买价格便宜,但是服务器机型固定;另一个是直接在云服务器…...
第四章 Opencv图像色彩空间与通道
文章目录1.色彩空间1-1.RGB/BGR色彩空间1-2.GRAY色彩空间1-3.HSV色彩空间2.通道2-1.拆分通道:split()方法1.拆BGR色彩空间图像的通道2.拆HSV色彩空间图像的通道2-2.合并通道:merge()方法1.B、G、R 通道的合并2.H、S、V 通道的合并3.B、G、R、A 通道的合并…...
《论文列表》持续更新中......
《论文列表》持续更新中......前言相关论文阅读说服对话系统 Persuasive Dialogue System情感知识对话 Emotional Support Conversation对话中的情感识别 Emotion Recognition in Conversation情感对话生成 Emotional Response Generation多模态融合情感识别或情感生成 Multimo…...
空间中任意一点到球的截面的最短距离
假设球的球心坐标为Oball{x0,y0,z0}O_{ball}\{x_0,y_0,z_0\}Oball{x0,y0,z0},球的半径为rrr,球的方程为(x−x0)2(y−y0)2(z−z0)2r2(x-x_0)^2(y-y_0)^2(z-z_0)^2r^2(x−x0)2(y−y0)2(z−z0)2r2球的一截面的方程为AxByCz10AxByCz10AxByCz10…...
麦克斯韦方程场分量公式推导
今天看书的时候遇到了一个关于公式推导的问题,阅读该篇前推荐优先阅读—点乘与叉乘是否满足结合律。 已知: E ⃗ t = i k n 2 (...
freertos学习之路6-任务创建和删除
写在最前 由于工作需要,需要开始学习freertos的相关知识,本专题主要记录freertos的相关内容 参考: https://www.bilibili.com/video/BV19g411p7UT 正点原子视频 1. 简介 和一般的OS不同(linux/windows),在…...
科都电气创业板IPO终止:曾计划募资约6亿元,郑春开等学历较低
近日,深圳证券交易所披露的信息显示,科都电气股份有限公司(下称“科都电气”)提交了撤回首次公开发行股票并在创业板上市申请文件的申请,同时保荐机构撤回对该公司的保荐。 因此,深圳证券交易所决定终止对…...
【MySQL】第十六部分 MySQL数据类型详解
【MySQL】第十六部分 MySQL数据类型详解 文章目录【MySQL】第十六部分 MySQL数据类型详解16. MySQL数据类型详解16.1 整数类型16.2 浮点类型16.3 定点数类型16.4 位类型 BIT16.5 日期和时间类型16.6 文本字符串类型16.6.1 CHAR VS VARCHAR类型16.6.2 TEXT类型16.6.3 ENUM类型16…...
Linux手工创建新用户
准备工作(配置流程的理解) Linux中useradd命令即一系列文件操作的结合体,所以我们可以通过查看useradd命令来确认我们手工创建新用户需要完成的文件配置 找到man useradd中涉及的文件部分 对于手工创建用户有用的文件: /etc/pas…...
K_A12_003 基于STM32等单片机采集光敏二极管模块参数 串口与OLED0.96双显示
K_A12_003 基于STM32等单片机采集光敏二极管模块参数 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RC光敏二极管模块1.2、STM32F103C8T6光敏二极管模块五、基础知识…...
天才少年稚晖君
稚晖君 简介主要成就华为天才少年简介 彭志辉,1993年出生于江西吉安,科技圈知名KOL,人称“稚晖君”“野生钢铁侠”,原华为天才少年。 2015年本科毕业于电子科技大学生命科学与技术学院;2018年研究生毕业于电子科技大学信息与通信工程学院;毕业后就职于OPPO研究院AI实验…...
【Linux command 09】tcpdump 命令
tcp一款sniffer工具,是Linux上的抓包工具,嗅探器语法tcpdump (选项)选项-c: 指定要抓取的包数量。注意,是最终要获取这么多个包。例如,指定"-c 10"将获取10个包,但可能已经处理了100个包…...
初始结构体
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🏡前言 🐰结构体的基础知识 🐰结构体的声明 &#x…...
English Learning - Day56 作业打卡 2023.2.10 周五
English Learning - Day56 作业打卡 2023.2.10 周五引言1. 他把车停错了地方,因此被罚了款。2. 这个事我越想越生气。3.他在这工作的时间比我长。4. 没有奋斗,就不会变强大。5.我一到北京就给你打电话。6. 直到我有了孩子,才意识到我的父母有…...
Python中五个不常见的隐晦用法小结
1. 引言 我已经用Python编程5年了(从2017年开始),直到最近才知道以下几个Python中不常见的用法,确实和人们对直观理解有所出入。 闲话少说,我们直接开始吧! 2. 类中的私有变量不是真正的私有 我们直接上…...
SharkTeam:Move合约开发与合约安全
近期,围绕 Aptos 和 Sui,新兴的高性能 L1链 以及这些新链背后的 Move 智能合约编程语言引起了很多关注,社区也非常活跃,很多开发者和项目已经开始积极转向 Move。但Move相对Solidity差别较大,即使是相对比较接近的Rust…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
