JetPack——Lifecycle
Lifecycle是什么?
Lifecycle 是一个类,用于存储有关组件(如 activity 或 fragment)的生命周期状态的信息,并允许其他对象观测此状态
Lifeclcle解决什么问题?
class GPS(private val context: Context,private val callback: (GpsSTATE) -> Unit
) {private val TAG = "GPS"private var gpsState = GpsSTATE.CLOSEenum class GpsSTATE {CLOSE, OPEN}private fun prepareGps(): Boolean {Thread.sleep(3000)return true}fun start() {Thread {if (prepareGps()) {if (gpsState === GpsSTATE.CLOSE) {Log.d(TAG, "start: 开启gps")gpsState = GpsSTATE.OPENstateChange()}}}.start()}fun stop() {Thread {if (gpsState === GpsSTATE.OPEN) {gpsState = GpsSTATE.CLOSELog.d(TAG, "stop: 关闭gps")stateChange()}}.start()}private fun stateChange() {(context as Activity).runOnUiThread {callback.invoke(gpsState)}}
}
对于如上的GPS类,需要在onStart()时开启、onStop()时关闭
class MainActivity : AppCompatActivity() {private val TAG = "MainActivity"private lateinit var mGPS: GPSprivate var tv: TextView? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)tv = findViewById<TextView>(R.id.tv)mGPS = GPS(this) {when (it) {GPS.GpsSTATE.CLOSE -> {Log.d(TAG, "UI change: GPS close")tv!!.text = "GPS close"}GPS.GpsSTATE.OPEN -> {Log.d(TAG, "UI change: GPS open")tv!!.text = "GPS open"}}}}public override fun onStart() {super.onStart()Log.d(TAG, "onStart: ")mGPS.start()}public override fun onStop() {super.onStop()Log.d(TAG, "onStop: ")mGPS.stop()}override fun onDestroy() {super.onDestroy()Log.d(TAG, "onDestroy: ")tv = null}
}
但在实际中,GPS类会在多个Activity/Fragment中使用从而产生大量样板代码,且上述代码在start()进行了耗时操作,在其完成前按返回键退出Activity,会错误的开启GPS且通过回调修改已经置空的UI导致报错
Lifecycle实现
本文使用的版本如下,版本不一样需要更新AS及Gradle
修改GPS类
- 实现DefaultLifecycleObserver,监听Activity的onStart()和onStop()处理业务
- 在状态至少为started的时候才开启GPS并回调更新UI
class GPS(private val context: Context,private val lifecycle: Lifecycle,private val callback: (GpsSTATE) -> Unit
) : DefaultLifecycleObserver {private val TAG = "GPS"private var gpsState = GpsSTATE.CLOSEenum class GpsSTATE {CLOSE, OPEN}private fun prepareGps(): Boolean {Thread.sleep(3000)return true}override fun onStart(owner: LifecycleOwner) {Thread {if (prepareGps()) {if (gpsState === GpsSTATE.CLOSE && lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {Log.d(TAG, "start: 开启gps")gpsState = GpsSTATE.OPENstateChange()}}}.start()}override fun onStop(owner: LifecycleOwner) {Thread {if (gpsState === GpsSTATE.OPEN) {gpsState = GpsSTATE.CLOSELog.d(TAG, "stop: 关闭gps")stateChange()}}.start()}private fun stateChange() {(context as Activity).runOnUiThread {callback.invoke(gpsState)}}
}
修改MainActivity,传入lifecycle和回调,注册监听,修改后的代码可以实现相同功能并解决问题,减少重复代码
class MainActivity : AppCompatActivity() {private val TAG = "MainActivity"private lateinit var mGPS: GPSprivate var tv: TextView? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)tv = findViewById<TextView>(R.id.tv)mGPS = GPS(this, lifecycle) {when (it) {GPS.GpsSTATE.CLOSE -> {Log.d(TAG, "UI change: GPS close")tv!!.text = "GPS close"}GPS.GpsSTATE.OPEN -> {Log.d(TAG, "UI change: GPS open")tv!!.text = "GPS open"}}}lifecycle.addObserver(mGPS)}public override fun onStart() {super.onStart()Log.d(TAG, "onStart: ")}public override fun onStop() {super.onStop()Log.d(TAG, "onStop: ")}override fun onDestroy() {super.onDestroy()Log.d(TAG, "onDestroy: ")tv = null}
}
Lifecyclcle源码解析
LifecycleOwner
LifecycleOwner维护自身生命周期的Lifecycle变量
public interface LifecycleOwner {public val lifecycle: Lifecycle
}
Lifecycle
可向LifecycleOwner注册/取消监听LifecycleObserver(需在主线程)
通过Event和State来描述LifecycleOwner的生命周期变化(关系如下图),其中Any匹配所有Event,isAtLeast()判断当前状态是否大于指定状态
public abstract class Lifecycle {@MainThreadpublic abstract fun addObserver(observer: LifecycleObserver)@MainThreadpublic abstract fun removeObserver(observer: LifecycleObserver)@get:MainThreadpublic abstract val currentState: Statepublic enum class Event {ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY,ON_ANY;public val targetState: Stateget() {when (this) {ON_CREATE, ON_STOP -> return State.CREATEDON_START, ON_PAUSE -> return State.STARTEDON_RESUME -> return State.RESUMEDON_DESTROY -> return State.DESTROYEDON_ANY -> {}}throw IllegalArgumentException("$this has no target state")}public companion object {@JvmStaticpublic fun downFrom(state: State): Event? {return when (state) {State.CREATED -> ON_DESTROYState.STARTED -> ON_STOPState.RESUMED -> ON_PAUSEelse -> null}}@JvmStaticpublic fun downTo(state: State): Event? {return when (state) {State.DESTROYED -> ON_DESTROYState.CREATED -> ON_STOPState.STARTED -> ON_PAUSEelse -> null}}@JvmStaticpublic fun upFrom(state: State): Event? {return when (state) {State.INITIALIZED -> ON_CREATEState.CREATED -> ON_STARTState.STARTED -> ON_RESUMEelse -> null}}@JvmStaticpublic fun upTo(state: State): Event? {return when (state) {State.CREATED -> ON_CREATEState.STARTED -> ON_STARTState.RESUMED -> ON_RESUMEelse -> null}}}}public enum class State {DESTROYED,INITIALIZED,CREATED,STARTED,RESUMED;public fun isAtLeast(state: State): Boolean {return compareTo(state) >= 0}}
}
LifecycleRegistry
Lifecycle是抽象类,其实现类是LifecycleRegistry
- 通过Map存储LifecycleObserver和ObserverWithState
- 当currentState变化或调用handleLifecycleEvent()时,调用moveToState()、sync()、forwardPass()/backwardPass()、ObserverWithState中LifecycleEventObserver的dispatchEvent()、onStateChanged()
open class LifecycleRegistry private constructor(provider: LifecycleOwner,private val enforceMainThread: Boolean
) : Lifecycle() {private var observerMap = FastSafeIterableMap<LifecycleObserver, ObserverWithState>()private var state: State = State.INITIALIZEDoverride var currentState: Stateget() = stateset(state) {enforceMainThreadIfNeeded("setCurrentState")moveToState(state)}open fun handleLifecycleEvent(event: Event) {enforceMainThreadIfNeeded("handleLifecycleEvent")moveToState(event.targetState)}private fun moveToState(next: State) {if (state == next) {return}check(!(state == State.INITIALIZED && next == State.DESTROYED)) {"no event down from $state in component ${lifecycleOwner.get()}"}state = nextif (handlingEvent || addingObserverCounter != 0) {newEventOccurred = true// we will figure out what to do on upper level.return}handlingEvent = truesync()handlingEvent = falseif (state == State.DESTROYED) {observerMap = FastSafeIterableMap()}}override fun addObserver(observer: LifecycleObserver) {enforceMainThreadIfNeeded("addObserver")val initialState = if (state == State.DESTROYED) State.DESTROYED else State.INITIALIZEDval statefulObserver = ObserverWithState(observer, initialState)val previous = observerMap.putIfAbsent(observer, statefulObserver)if (previous != null) {return}val lifecycleOwner = lifecycleOwner.get()?: // it is null we should be destroyed. Fallback quicklyreturnval isReentrance = addingObserverCounter != 0 || handlingEventvar targetState = calculateTargetState(observer)addingObserverCounter++while (statefulObserver.state < targetState && observerMap.contains(observer)) {pushParentState(statefulObserver.state)val event = Event.upFrom(statefulObserver.state)?: throw IllegalStateException("no event up from ${statefulObserver.state}")statefulObserver.dispatchEvent(lifecycleOwner, event)popParentState()// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer)}if (!isReentrance) {// we do sync only on the top level.sync()}addingObserverCounter--}override fun removeObserver(observer: LifecycleObserver) {enforceMainThreadIfNeeded("removeObserver")observerMap.remove(observer)}private fun forwardPass(lifecycleOwner: LifecycleOwner) {@Suppress()val ascendingIterator: Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> =observerMap.iteratorWithAdditions()while (ascendingIterator.hasNext() && !newEventOccurred) {val (key, observer) = ascendingIterator.next()while (observer.state < state && !newEventOccurred && observerMap.contains(key)) {pushParentState(observer.state)val event = Event.upFrom(observer.state)?: throw IllegalStateException("no event up from ${observer.state}")observer.dispatchEvent(lifecycleOwner, event)popParentState()}}}private fun backwardPass(lifecycleOwner: LifecycleOwner) {val descendingIterator = observerMap.descendingIterator()while (descendingIterator.hasNext() && !newEventOccurred) {val (key, observer) = descendingIterator.next()while (observer.state > state && !newEventOccurred && observerMap.contains(key)) {val event = Event.downFrom(observer.state)?: throw IllegalStateException("no event down from ${observer.state}")pushParentState(event.targetState)observer.dispatchEvent(lifecycleOwner, event)popParentState()}}}private fun sync() {val lifecycleOwner = lifecycleOwner.get()?: throw IllegalStateException("LifecycleOwner of this LifecycleRegistry is already " +"garbage collected. It is too late to change lifecycle state.")while (!isSynced) {newEventOccurred = falseif (state < observerMap.eldest()!!.value.state) {backwardPass(lifecycleOwner)}val newest = observerMap.newest()if (!newEventOccurred && newest != null && state > newest.value.state) {forwardPass(lifecycleOwner)}}newEventOccurred = false}@SuppressLint("RestrictedApi")private fun enforceMainThreadIfNeeded(methodName: String) {if (enforceMainThread) {check(ArchTaskExecutor.getInstance().isMainThread) {("Method $methodName must be called on the main thread")}}}internal class ObserverWithState(observer: LifecycleObserver?, initialState: State) {var state: Statevar lifecycleObserver: LifecycleEventObserverinit {lifecycleObserver = Lifecycling.lifecycleEventObserver(observer!!)state = initialState}fun dispatchEvent(owner: LifecycleOwner?, event: Event) {val newState = event.targetStatestate = min(state, newState)lifecycleObserver.onStateChanged(owner!!, event)state = newState}}
}
在ObserverWithState中为了兼容,需要通过Lifecycling.lifecycleEventObserver()判断是LifecycleEventObserver还是DefaultLifecycleObserver
public fun lifecycleEventObserver(`object`: Any): LifecycleEventObserver {val isLifecycleEventObserver = `object` is LifecycleEventObserverval isDefaultLifecycleObserver = `object` is DefaultLifecycleObserverif (isLifecycleEventObserver && isDefaultLifecycleObserver) {return DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver,`object` as LifecycleEventObserver)}if (isDefaultLifecycleObserver) {return DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver, null)}if (isLifecycleEventObserver) {return `object` as LifecycleEventObserver}......}
若是LifecycleEventObserver直接返回,若是DefaultLifecycleObserver则需要创建DefaultLifecycleObserverAdapter适配
internal class DefaultLifecycleObserverAdapter(private val defaultLifecycleObserver: DefaultLifecycleObserver,private val lifecycleEventObserver: LifecycleEventObserver?
) : LifecycleEventObserver {override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {when (event) {Lifecycle.Event.ON_CREATE -> defaultLifecycleObserver.onCreate(source)Lifecycle.Event.ON_START -> defaultLifecycleObserver.onStart(source)Lifecycle.Event.ON_RESUME -> defaultLifecycleObserver.onResume(source)Lifecycle.Event.ON_PAUSE -> defaultLifecycleObserver.onPause(source)Lifecycle.Event.ON_STOP -> defaultLifecycleObserver.onStop(source)Lifecycle.Event.ON_DESTROY -> defaultLifecycleObserver.onDestroy(source)Lifecycle.Event.ON_ANY ->throw IllegalArgumentException("ON_ANY must not been send by anybody")}lifecycleEventObserver?.onStateChanged(source, event)}
}
LifecycleObserver
LifecycleObserver只是一个接口,其实现类有LifecycleEventObserver和DefaultLifecycleObserver
public interface LifecycleObserver
LifecycleEventObserver
重写onStateChanged(),得到LifecycleOwner和Lifecycle.Event,判断当前所在生命周期
public fun interface LifecycleEventObserver : LifecycleObserver {public fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event)
}
DefaultLifecycleObserver
重写相关方法可直接监听生命周期
public interface DefaultLifecycleObserver : LifecycleObserver {public fun onCreate(owner: LifecycleOwner) {}public fun onStart(owner: LifecycleOwner) {}public fun onResume(owner: LifecycleOwner) {}public fun onPause(owner: LifecycleOwner) {}public fun onStop(owner: LifecycleOwner) {}public fun onDestroy(owner: LifecycleOwner) {}
}
FragmentActivity
自定义Activity继承AppCompatActivity,再继承FragmentActivity,创建LifecycleRegistry并在对应生命周期方法调用handleLifecycleEvent()
public class FragmentActivity extends ComponentActivity implementsActivityCompat.OnRequestPermissionsResultCallback,ActivityCompat.RequestPermissionsRequestCodeValidator {final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);mFragments.dispatchCreate();}@Overrideprotected void onDestroy() {super.onDestroy();mFragments.dispatchDestroy();mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);}@Overrideprotected void onPause() {super.onPause();mResumed = false;mFragments.dispatchPause();mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);}@Overrideprotected void onPostResume() {super.onPostResume();onResumeFragments();}protected void onResumeFragments() {mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);mFragments.dispatchResume();}@Overrideprotected void onStart() {mFragments.noteStateNotSaved();super.onStart();......mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);mFragments.dispatchStart();}@Overrideprotected void onStop() {super.onStop();mStopped = true;markFragmentsCreated();mFragments.dispatchStop();mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);}
Fragment
同上,不再赘述
相关文章:
JetPack——Lifecycle
Lifecycle是什么? Lifecycle 是一个类,用于存储有关组件(如 activity 或 fragment)的生命周期状态的信息,并允许其他对象观测此状态 Lifeclcle解决什么问题? class GPS(private val context: Context,pr…...
本地小主机安装HomeAssistant开源智能家居平台打造个人AI管家
文章目录 前言1. 添加镜像源2. 部署HomeAssistant3. HA系统初始化配置4. HA系统添加智能设备4.1 添加已发现的设备4.2 添加HACS插件安装设备 5. 安装cpolar内网穿透5.1 配置HA公网地址 6. 配置固定公网地址 前言 大家好!今天我要向大家展示如何将一台迷你的香橙派Z…...
大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!
大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!DeepSeek-V3上线即开源;OpenAI 发布高级推理模型 o3https://mp.weixin.qq.com/s/9qU_zzIv9ibFdJZ5cTocOw?token47960959&langzh_CN 「青稞大模型Weekly」,持…...
【0379】Postgres内核 Walreceiver (libpqwalreceiver API)分析
文章目录 1. libpqwalreceiver API1.1 四个函数2. Walreceiver IPC3. Walsender IPC4. Walsender - walreceiver protocol1. libpqwalreceiver API walreceiver 中与传输相关的部分,其负责连接主服务器、接收 WAL 文件以及发送消息,是动态加载的,以避免主服务器的二进制文件…...
easybox
title: 解锁 EasyBox:智能运维的便捷之选 date: ‘2024-12-31’ category: blog tags: EasyBox智能运维效率提升自动化运维 sig: memsafety archives: ‘2024-12’ author:way_back summary: EasyBox 作为一款智能运维工具,以其简洁高效的特性ÿ…...
Prompt工程--AI开发--可置顶粘贴小工具
PROMPT 1.背景要求:我需要开发一个简单的粘贴小工具,用于方便地粘贴和管理文本内容。该工具需要具备以下功能:粘贴功能:提供一个文本框,用户可以粘贴内容。窗口置顶:支持窗口置顶功能,确保窗口…...
【AI日记】24.12.31 kaggle 比赛 2-19
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加:kaggle 比赛 Regression with an Insurance Dataset时间:9 小时 读书 书名:论婚姻与道德时间:1.5 小时 律己 工作时间:良作息&#x…...
jenkins集成工具(一)部署php项目
目录 什么是CI 、CD Jenkins集成工具 一、Jenkins介绍 二、jenkins的安装和部署 环境部署 安装jenkins 安装gitlab 配置镜像源进行安装 修改密码 安装git工具 上传测试代码 Jenkins部署php项目wordpress 发布php代码 安装插件 测试代码发布 实现发布成功发送邮件…...
ubuntu 使用samba与windows共享文件[注意权限配置]
在Ubuntu上使用Samba服务与Windows系统共享文件,需要正确配置Samba服务以及相应的权限。以下是详细的步骤: 安装Samba 首先,确保你的Ubuntu系统上安装了Samba服务。 sudo apt update sudo apt install samba配置Samba 安装完成后,…...
【GridView渐进全解】第四部分GridView分页进阶
目录 一、启用分页 二、修改GridView分页模板 1.进入控件模板修改视图: 2.进入页码模板(PagerTemplate)视图 3.添加导航按钮控件 4.修改导航控件属性 三、输入页号跳转 1.进入页码模板视图 2.添加文本框及按钮控件 3.编写代码 【接…...
K8s集群平滑升级(Smooth Upgrade of K8S Cluster)
简介: Kubernetes (简称K8s)是一个开源的容器编排和管理平台,由Google开发并维护。它最初是为了解决谷歌内部大规模容器管理的问题而设计的,后来在2014年开源,成为云原生技术的核心组成部分。1 K8…...
HarmonyOS-面试整理
目录 为什么选择HarmonyOS/ 优点/特点鸿蒙系统的权限有哪些说一说鸿蒙系统的安全机制说一说鸿蒙系统的微内核与安卓的内核区别鸿蒙操作系统的微内核架构有哪些优势分布式能力在鸿蒙系统中如何实现请解释一下鸿蒙系统中的分布式软总线技术如何在鸿蒙操作系统中进行多设备协同开发…...
基于编程语言的知识图谱表示增强大模型推理能力研究,一种提升LLM推理准确率达91.5%的结构化数据方法
基于编程语言的知识图谱表示增强大模型推理能力研究,一种提升LLM推理准确率达91.5%的结构化数据方法 理解数据分析全流程提问问题:知识的表示方式如何影响模型的推理能力?问题:为什么编程语言会是一个更好的知识表示选择ÿ…...
【北京迅为】iTOP-4412全能版使用手册-第七十章 Linux内核移植
iTOP-4412全能版采用四核Cortex-A9,主频为1.4GHz-1.6GHz,配备S5M8767 电源管理,集成USB HUB,选用高品质板对板连接器稳定可靠,大厂生产,做工精良。接口一应俱全,开发更简单,搭载全网通4G、支持WIFI、蓝牙、…...
使用 ASP.NET Core wwwroot 上传和存储文件
在 ASP.NET Core 应用程序中上传和存储文件是用户个人资料、产品目录等功能的常见要求。本指南将解释使用wwwroot存储图像(可用于文件)的过程以及如何在应用程序中处理图像上传。 步骤 1:设置项目环境 确保您的 ASP.NET 项目中具有必要的依…...
什么是 Azure OpenAI ?了解微软 Azure OpenAI 和 OpenAI 的关系
一、什么是Azure OpenAI ? 微软已与 OpenAI 合作以实现三个主要目标: ⦿利用 Azure 的基础结构(包括安全性、合规性和区域可用性),帮助用户构建企业级应用程序。 ⦿在微软产品(包括 Azure AI 产品以及以外…...
Flink CDC 自定义函数处理 SQLServer XML类型数据 映射 doris json字段方案
Flink CDC 自定义函数处理 SQLServer XML类型数据方案 1. 背景 因业务使用SQLServer数据库,CDC同步到doris 数仓。对于SQLServer xml类型,doris没有相应的字段对应, 可以使用json来存储xml数据。需要进行一步转换。从 flink 自定义函数入手…...
导致启动nacos报错Caused by: java.lang.IllegalStateException: No DataSource set 的两种原因
Java资深小白,不足之处,或者有任何错误欢迎指出。 --蓝紫报错代码如下: C:\Windows\System32>cd D:\nacos-server-2.2.3\nacos\binC:\Windows\System32>d:D:\nacos-server-2.2.3\nacos\bin>startup.cmd -m standalone "nacos is starting…...
mysql乱码、mysql数据中文问号
网上排出此错误方法的很多,但是 都不简洁,找不到根本原因 主要排查两点: 1.代码中jdbc链接的编码规则 urljdbc:mysql://localhost:3306/title?useUnicodetrue&characterEncodingutf8 将characterEncoding设置为utf8 2.设置mysq…...
python RAG 管道
RAG(RetrievalAugmented Generation)管道是一种结合了信息检索(Retrieval)和文本生成(Generation)的技术框架,主要用于生成高质量、基于事实的文本。它通过从外部知识源(如文档、数据…...
018-spring-基于aop的事务控制
1 先配置平台事务管理器 2 在配置 spring提供的advice 3 事务增强的aop 总结: 事务就是要做2个配置: <!-- 1 开启事务管理器 不同的框架对应不同的事务管理器 --> <bean id"transactionManager" class"org.springframework.j…...
HTML 轮播图(Carousel)详细讲解
HTML 轮播图(Carousel)详细讲解 轮播图(Carousel)是一种常见的用户界面组件,用于在同一位置展示多个图像或内容,允许用户通过滑动或自动播放的方式查看不同的内容。它通常用于展示产品、图片、广告等。 1…...
计算机网络-数据链路层(ppp协议)
2.2 ppp协议 点对点协议ppp是目前使用最广泛的点对点数据链路层协议。 2.3 媒体接入控制基本概念 共享信道要着重考虑的一个问题就是如何协调多个发送和接收站点对一个共享传输媒体的占用,即媒体接入控制MAC。 2.3.1 静态划分信道 频分复用 时分复用 波分复用 码分复…...
如何优化Python网络爬虫的数据清洗流程,以提升数据质量并有效应对网站反爬虫机制?
优化爬虫数据清洗流程,应对反爬虫机制 一、数据清洗的重要性 在网络爬虫中,数据清洗是关键环节。打个比方,我们从网页抓取到的原始数据就像一堆杂乱的杂物,里面有各种格式、错误和重复信息。比如抓取到的文本可能包含HTML标签、…...
QSharedMemory 实现数据exe间共享
定义共享数据结构 首先,需要定义一个结构体来包含要共享的数据。这个结构体应该包含所有需要在多个类的实例之间共享的成员变量 struct SharedData {int intValue;QString stringValue;// 可以添加更多需要共享的成员变量}; 使用 QSharedMemory 进行数据共享 在写…...
强化学习(1)
Reinforcement Learning Goal-directed learing from ineraction with the environment. 1. Basic Element 基本元素 1.1 Agent 玩家 1.2 Environment 1.3 Goal 2. Main Element 主要元素 2.1 State 2.2 Action 状态与行为往复 2.3 Reward 目标:最大化总…...
Spring Boot 嵌套事务详解及失效解决方案
在复杂的业务场景中,嵌套事务可以帮助我们更加精细地控制数据的一致性。然而,在 Spring Boot 中,如果嵌套事务的配置不当,可能会导致事务不生效的问题,尤其是在同一个类中进行方法调用时。 本文将详细介绍嵌套事务的原…...
IDEA 社区版 SpringBoot不能启动
报错原因,Failed to load class [javax.servlet.Filter] <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope> </dependency>…...
【SQL server】教材数据库(4)
学生(学号,年龄,性别,系名) 教材(编号,书名,出版社编号,价格) 订购(学号,书号,数量) 出版社(编…...
px、em、rem,vw区别介绍
在网页设计中,px、em、rem 和 vw 都是常用的 CSS 单位,它们各自有不同的用途和特性。下面是这些单位的详细介绍及其区别: 1. px(像素) 定义: px 是最常用的绝对单位,表示屏幕上的一个物理像素…...
pip安装paddle失败
一、pip安装paddle失败,报错如下 Preparing metadata (setup.py) ... error error: subprocess-exited-with-error import common, dual, tight, data, prox ModuleNotFoundError: No module named common [end of output] 二、解决方法: 按照提示安装对…...
QWT 之 QwtPlotDirectPainter直接绘制
QwtPlotDirectPainter 是 Qwt 库中用于直接在 QwtPlot 的画布上绘制图形的一个类。它提供了一种高效的方法来实时更新图表,特别适合需要频繁更新的数据可视化应用,例如实时数据流的显示。 使用 QwtPlotDirectPainter 的主要优势在于它可以绕过 QwtPlot 的…...
编辑音频的基本属性
导入音频 “文件-导入-选择音频”拖到音频轨道创建序列。选择音频,在效果空间可以看到音频的基本属性。 音量的设置 “效果工作区-效果控件-音量”在这里可以控制所有引导的混合音量 静音 静止所有声音 音频仪表 一般位于时间轴的后面,找不到可以…...
【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-44
文件下载与邀请翻译者 学习英特尔开发手册,最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册,会是一件耗时费力的工作。如果有愿意和我一起来做这件事的,那么ÿ…...
格式化输出年月日
直接上图 结论:老老实实用yyyy,得到的年月日是我们口头上说的时间,而YYYY有点反人类.... 对于一年的最后一周的一些日子,会统计成下一年; 对于下一年的第一周的一些日子,会统计成上一年; 你猜…...
解决Spring boot集成quartz时service注入失败为null的问题
解决Spring boot集成quartz时service注入失败为null的问题 一、报错信息二、代码任务类源代码配置类原代码 三、注入失败原因四、解决的思路11、任务类修改2、配置类修改 五、 解决的思路2 一、报错信息 java.lang.NullPointerException: null at farbun.server.scheduledTask…...
Python 青铜宝剑十六维,破医疗数智化难关(下)
九、模型可靠性的验证秘籍 在医疗数智化进程中,模型可靠性宛如一座灯塔,为精准医疗决策指引方向。以疾病诊断模型为例,一旦模型可靠性存疑,在癌症早期筛查场景下,可能将良性病变误判为恶性,让患者承受不必要的痛苦与恐慌,又或是遗漏细微癌变迹象,延误最佳治疗时机;在…...
初识具身智能
具身智能是智能科学的一个基础问题,在过去的5.4亿年以来,地球上所有生物都是通过身体和环境交互、进化逐步产生的。通俗地讲,具身智能体以第一人称视角身临其境地从环境交互中理解外部世界的本质概念,被认为是通向通用人工智能的重…...
Node 使用pkg打包部署
一、安装pkg(不太好装,需要借助国内镜像) npm install -g pkg --registryhttps://registry.npm.taobao.org 二、配置package.jsonsan // package.json ,配置专门制定pkg的执行入口 { ... "bin": "main.js", "pkg":{"assets&q…...
计算机网络-L2TP Over IPSec基础实验
一、概述 上次我们进行了标准L2TP的配置,但是在最后我们在进行业务流量访问时看到流量是没有进行加密的,这就导致可能得安全风险,所以这里其实可以退像GRE那样调用IPSec框架来进行加密保护。 拓扑 数据不加密 现在需要配置IPSec,然…...
Java工程师实现视频文件上传minio文件系统存储及网页实现分批加载视频播放
Java工程师实现minio存储大型视频文件网页实现分批加载视频播放 一、需求说明 老板给我出个题目,让我把的电影文件上传到minio文件系统,再通过WEB端分配加载视频播放,类似于我们普通的电影网站。小编把Java代码共享出来。是真正的能拿过来直…...
html5css3
1.html5新增语义化标签 <header><nav><article><section><aside><footer> 2.新增多媒体标签 视频<video>格式:map4,webm,ogg <video controls"controls" autoplay"autoplay" muted"mute…...
运维人员的Go语言学习路线
以下是一份更为详细的适合运维人员的Go语言学习路线图: 一、基础环境搭建与入门(第 1 - 2 周) 第 1 周 环境搭建 在本地开发机和常用的运维服务器环境(如 Linux 系统)中安装 Go 语言。从官方网站(https://…...
怎么在家访问公司服务器?
在日常工作中,特别是对信息技术从业者而言,工作往往离不开公司的服务器。他们需要定期访问服务器,获取一些关键的机密文件或数据。如果您在家办公,并且需要处理未完成的任务,同时需要从公司服务器获取所需的数据&#…...
【linux学习指南】】Ext系列文件系统(三)ext2 文件系统的认识与构成
文章目录 📝ext2 ⽂件系统🌠 宏观认识🌉 Block Group 🌠块组内部构成🌉超级块(SuperBlock) 🌠GDT(GroupDescriptorTable)🌉块位图(Blo…...
区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】
区块链安全常见的攻击分析——Unprotected callback - ERC721 SafeMint reentrancy【8】 1.1 漏洞分析1.2 漏洞合约1.3 攻击分析1.4 攻击合约 重点:MaxMint721 漏洞合约的 mint 函数调用了 ERC721 合约中的 _checkOnERC721Received 函数,触发 to 地址中实…...
Linux中sed命令的使用技巧
一、sed语法介绍 sed命令主要用于文本内容的编辑,默认只处理模式空间,不处理原数据。 命令格式: sed [option] command filename示例:删除空白行 sed ‘/^\s*$/d’ filename option 参数: -n:只有经过sed…...
小米路由器开启SSH,配置阿里云ddns,开启外网访问SSH和WEB管理界面
文章目录 前言一、开启SSH二、配置阿里云ddns1.准备工作2.创建ddns脚本3.添加定时任务 三、开启外网访问SSH和WEB管理界面1、解除WEB管理页面访问限制2.手动添加防火墙端口转发规则,开启外网访问WEB管理和SSH 前言 例如:随着人工智能的不断发展…...
Flink源码解析之:如何根据JobGraph生成ExecutionGraph
Flink源码解析之:如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中,我们介绍了Flink如何根据StreamGraph生成JobGraph的流程,并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…...
活动预告 |【Part2】Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识
课程介绍 通过参加“Microsoft 安全在线技术公开课:安全性、合规性和身份基础知识”活动提升你的技能。在本次免费的介绍性活动中,你将获得所需的安全技能和培训,以创造影响力并利用机会推动职业发展。你将了解安全性、合规性和身份的基础知…...