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

菜单中的类似iOS中开关的样式

背景是我们有需求,做类似ios中开关的按钮。github上有一些开源项目,比如 SwitchButton, 但是这个项目中提供了很多选项,并且实际使用中会出现一些奇怪的问题。

我调整了下代码,把无关的功能都给删了,保留核心的功能,大概这样。

在这里插入图片描述
在这里插入图片描述

package org.yeshen.widget;// 修改自:https://github.com/zcweng/SwitchButton
// 菜单中的类似iOS中开关的样式import static org.yeshen.widget.YsSwitchButton.ANIMATE.*;import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Checkable;public final class YsSwitchButton extends View implements Checkable {private static final int DEFAULT_WIDTH = dp2pxInt(44);private static final int DEFAULT_HEIGHT = dp2pxInt(25);private static final int DEFAULT_BUTTON_PADDING = dp2pxInt(8);private final int uncheckColor = 0xFFFF0000;private final int checkedColor = 0xFF0000FF;private final int uncheckButtonColor = Color.WHITE;private float viewRadius;private float left;private float top;private float right;private float bottom;private float centerY;private float buttonMinX;private float buttonMaxX;private final Paint buttonPaint;private final Paint paint;private final ViewState viewState;private final ViewState beforeState;private final ViewState afterState;private final RectF rect = new RectF();private ANIMATE animateState = ANIMATE_STATE_NONE;private final ValueAnimator valueAnimator;private final android.animation.ArgbEvaluator argbEvaluator = new android.animation.ArgbEvaluator();private boolean isChecked = false;private boolean isTouchingDown = false;private boolean isUiInit = false;private boolean isEventBroadcast = false;private OnCheckedChangeListener onCheckedChangeListener;private long touchDownTime;private boolean switchByUser;public YsSwitchButton(Context context) {this(context, null);}public YsSwitchButton(Context context, AttributeSet attrs) {this(context, attrs, 0);}public YsSwitchButton(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paint = new Paint(Paint.ANTI_ALIAS_FLAG);buttonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);buttonPaint.setColor(uncheckButtonColor);viewState = new ViewState();beforeState = new ViewState();afterState = new ViewState();valueAnimator = ValueAnimator.ofFloat(0f, 1f);valueAnimator.setDuration(300);valueAnimator.setRepeatCount(0);ValueAnimator.AnimatorUpdateListener animatorUpdateListener = animation -> {float value = (Float) animation.getAnimatedValue();switch (animateState) {case ANIMATE_STATE_PENDING_SETTLE: {}case ANIMATE_STATE_PENDING_RESET: {}case ANIMATE_STATE_PENDING_DRAG: {if (animateState != ANIMATE_STATE_PENDING_DRAG) {viewState.buttonX = beforeState.buttonX + (afterState.buttonX - beforeState.buttonX) * value;}viewState.checkStateColor = (int) argbEvaluator.evaluate(value, beforeState.checkStateColor, afterState.checkStateColor);break;}case ANIMATE_STATE_SWITCH: {viewState.buttonX = beforeState.buttonX + (afterState.buttonX - beforeState.buttonX) * value;float fraction = (viewState.buttonX - buttonMinX) / (buttonMaxX - buttonMinX);viewState.checkStateColor = (int) argbEvaluator.evaluate(fraction, uncheckColor, checkedColor);break;}default:case ANIMATE_STATE_DRAGING: {}case ANIMATE_STATE_NONE: {break;}}postInvalidate();};valueAnimator.addUpdateListener(animatorUpdateListener);Animator.AnimatorListener animatorListener = new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) {}@Overridepublic void onAnimationEnd(Animator animation) {switch (animateState) {case ANIMATE_STATE_PENDING_DRAG: {animateState = ANIMATE_STATE_DRAGING;postInvalidate();break;}case ANIMATE_STATE_PENDING_RESET: {animateState = ANIMATE_STATE_NONE;postInvalidate();break;}case ANIMATE_STATE_PENDING_SETTLE: {animateState = ANIMATE_STATE_NONE;postInvalidate();broadcastEvent(true);break;}case ANIMATE_STATE_SWITCH: {isChecked = !isChecked;animateState = ANIMATE_STATE_NONE;postInvalidate();broadcastEvent(switchByUser);break;}case ANIMATE_STATE_DRAGING:case ANIMATE_STATE_NONE:default: {break;}}}@Overridepublic void onAnimationCancel(Animator animation) {}@Overridepublic void onAnimationRepeat(Animator animation) {}};valueAnimator.addListener(animatorListener);super.setClickable(true);this.setPadding(0, 0, 0, 0);setLayerType(LAYER_TYPE_SOFTWARE, null);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {final int widthMode = MeasureSpec.getMode(widthMeasureSpec);final int heightMode = MeasureSpec.getMode(heightMeasureSpec);if (widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST) {widthMeasureSpec = MeasureSpec.makeMeasureSpec(DEFAULT_WIDTH, MeasureSpec.EXACTLY);}if (heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST) {heightMeasureSpec = MeasureSpec.makeMeasureSpec(DEFAULT_HEIGHT, MeasureSpec.EXACTLY);}super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);float viewPadding = 0;float height = h - viewPadding - viewPadding;viewRadius = height * .5f;left = viewPadding;top = viewPadding;right = w - viewPadding;bottom = h - viewPadding;centerY = (top + bottom) * .5f;buttonMinX = left + viewRadius;buttonMaxX = right - viewRadius;if (isChecked()) {setCheckedViewState(viewState);} else {setUncheckViewState(viewState);}isUiInit = true;postInvalidate();}private void setUncheckViewState(ViewState viewState) {viewState.checkStateColor = uncheckColor;viewState.buttonX = buttonMinX;buttonPaint.setColor(uncheckButtonColor);}private void setCheckedViewState(ViewState viewState) {viewState.checkStateColor = checkedColor;viewState.buttonX = buttonMaxX;int checkedButtonColor = Color.WHITE;buttonPaint.setColor(checkedButtonColor);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// background colorpaint.setColor(uncheckColor);drawRoundRect(canvas, left, top, right, bottom, viewRadius, paint);// select colorpaint.setColor(viewState.checkStateColor);drawRoundRect(canvas, left, top, right, bottom, viewRadius, paint);// buttoncanvas.drawCircle(viewState.buttonX, centerY,viewRadius - DEFAULT_BUTTON_PADDING / 2F, buttonPaint);}@SuppressLint("ObsoleteSdkInt")private void drawRoundRect(Canvas canvas, float left, float top, float right,float bottom, float backgroundRadius, Paint paint) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {canvas.drawRoundRect(left, top, right, bottom, backgroundRadius, backgroundRadius, paint);} else {rect.set(left, top, right, bottom);canvas.drawRoundRect(rect, backgroundRadius, backgroundRadius, paint);}}@Overridepublic void setChecked(boolean checked) {if (checked == isChecked()) {postInvalidate();return;}toggle(true, false);}@Overridepublic boolean isChecked() {return isChecked;}@Overridepublic void toggle() {toggle(true);}public void toggle(boolean animate) {toggle(animate, true);}private void toggle(boolean animate, boolean broadcast) {toggle(animate, broadcast, false);}private void toggle(boolean animate, boolean broadcast, boolean byUser) {if (!isEnabled()) {return;}if (isEventBroadcast) {throw new RuntimeException("should NOT switch the state in method: [onCheckedChanged]!");}if (!isUiInit) {isChecked = !isChecked;if (broadcast) {broadcastEvent(byUser);}return;}if (valueAnimator.isRunning()) {valueAnimator.cancel();}if (!animate) {isChecked = !isChecked;if (isChecked()) {setCheckedViewState(viewState);} else {setUncheckViewState(viewState);}postInvalidate();if (broadcast) {broadcastEvent(byUser);}return;}animateState = ANIMATE_STATE_SWITCH;switchByUser = byUser;beforeState.copy(viewState);if (isChecked()) {setUncheckViewState(afterState);} else {setCheckedViewState(afterState);}valueAnimator.start();}private void broadcastEvent(boolean byUser) {if (onCheckedChangeListener != null) {isEventBroadcast = true;onCheckedChangeListener.onCheckedChanged(this, isChecked(), byUser);}isEventBroadcast = false;}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {if (!isEnabled()) {return false;}int actionMasked = event.getActionMasked();switch (actionMasked) {case MotionEvent.ACTION_DOWN: {isTouchingDown = true;touchDownTime = System.currentTimeMillis();removeCallbacks(postPendingDrag);postDelayed(postPendingDrag, 100);break;}case MotionEvent.ACTION_MOVE: {float eventX = event.getX();if (isPendingDragState()) {float fraction = eventX / getWidth();fraction = Math.max(0f, Math.min(1f, fraction));viewState.buttonX = buttonMinX + (buttonMaxX - buttonMinX) * fraction;} else if (isDragState()) {float fraction = eventX / getWidth();fraction = Math.max(0f, Math.min(1f, fraction));viewState.buttonX = buttonMinX + (buttonMaxX - buttonMinX) * fraction;viewState.checkStateColor = (int) argbEvaluator.evaluate(fraction, uncheckColor, checkedColor);postInvalidate();}break;}case MotionEvent.ACTION_UP: {isTouchingDown = false;removeCallbacks(postPendingDrag);if (System.currentTimeMillis() - touchDownTime <= 300) {toggle(true, true, true);} else if (isDragState()) {float eventX = event.getX();float fraction = eventX / getWidth();fraction = Math.max(0f, Math.min(1f, fraction));boolean newCheck = fraction > .5f;if (newCheck == isChecked()) {pendingCancelDragState();} else {isChecked = newCheck;pendingSettleState();}} else if (isPendingDragState()) {pendingCancelDragState();}break;}case MotionEvent.ACTION_CANCEL: {isTouchingDown = false;removeCallbacks(postPendingDrag);if (isPendingDragState() || isDragState()) {pendingCancelDragState();}break;}}return true;}private final Runnable postPendingDrag = () -> {if (!isInAnimating()) {pendingDragState();}};private boolean isInAnimating() {return animateState != ANIMATE_STATE_NONE;}private boolean isPendingDragState() {return animateState == ANIMATE_STATE_PENDING_DRAG || animateState == ANIMATE_STATE_PENDING_RESET;}private boolean isDragState() {return animateState == ANIMATE_STATE_DRAGING;}private void pendingDragState() {if (isInAnimating()) {return;}if (!isTouchingDown) {return;}if (valueAnimator.isRunning()) {valueAnimator.cancel();}animateState = ANIMATE_STATE_PENDING_DRAG;beforeState.copy(viewState);afterState.copy(viewState);if (isChecked()) {afterState.checkStateColor = checkedColor;afterState.buttonX = buttonMaxX;} else {afterState.checkStateColor = uncheckColor;afterState.buttonX = buttonMinX;}valueAnimator.start();}private void pendingCancelDragState() {if (isDragState() || isPendingDragState()) {if (valueAnimator.isRunning()) {valueAnimator.cancel();}animateState = ANIMATE_STATE_PENDING_RESET;beforeState.copy(viewState);if (isChecked()) {setCheckedViewState(afterState);} else {setUncheckViewState(afterState);}valueAnimator.start();}}private void pendingSettleState() {if (valueAnimator.isRunning()) {valueAnimator.cancel();}animateState = ANIMATE_STATE_PENDING_SETTLE;beforeState.copy(viewState);if (isChecked()) {setCheckedViewState(afterState);} else {setUncheckViewState(afterState);}valueAnimator.start();}@SuppressWarnings("unused")public void setOnCheckedChangeListener(OnCheckedChangeListener l) {onCheckedChangeListener = l;}public interface OnCheckedChangeListener {void onCheckedChanged(YsSwitchButton view, boolean isChecked, boolean byUser);}private static float dp2px(float dp) {Resources r = Resources.getSystem();return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());}private static int dp2pxInt(float dp) {return (int) dp2px(dp);}private static class ViewState {float buttonX;int checkStateColor;private void copy(ViewState source) {this.buttonX = source.buttonX;this.checkStateColor = source.checkStateColor;}}enum ANIMATE {ANIMATE_STATE_NONE, ANIMATE_STATE_PENDING_DRAG, ANIMATE_STATE_DRAGING, ANIMATE_STATE_PENDING_RESET, ANIMATE_STATE_PENDING_SETTLE, ANIMATE_STATE_SWITCH;}
}

相关文章:

菜单中的类似iOS中开关的样式

背景是我们有需求&#xff0c;做类似ios中开关的按钮。github上有一些开源项目&#xff0c;比如 SwitchButton&#xff0c; 但是这个项目中提供了很多选项&#xff0c;并且实际使用中会出现一些奇怪的问题。 我调整了下代码&#xff0c;把无关的功能都给删了&#xff0c;保留核…...

Vue 2 动态组件和异步组件

先阅读 【Vue 2 组件基础】中的初步了解动态组件。 动态组件与keep-alive 我们知道动态组件使用is属性和component标签结合来切换不同组件。 下面给出一个示例&#xff1a; <!DOCTYPE html> <html><head><title>Vue 动态组件</title><scri…...

MongoDB升级经历(4.0.23至5.0.19)

MongoDB从4.0.23至5.0.19升级经历 引子&#xff1a;为了解决MongoDB的两个漏洞决定把MongoDB升级至最新版本&#xff0c;期间也踩了不少坑&#xff0c;在这里分享出来供大家学习与避坑~ 1、MongoDB的两个漏洞 漏洞1&#xff1a;MongoDB Server 安全漏洞(CVE-2021-20330) 漏洞2…...

iPhone上的个人热点丢失了怎么办?如何修复iPhone上不见的个人热点?

个人热点功能可将我们的iPhone手机转变为 Wi-Fi 热点&#xff0c;有了Wi-Fi 热点后就可以与附近的其他设备共享其互联网连接。 一般情况下&#xff0c;个人热点打开就可以使用&#xff0c;但也有部分用户在升级系统或越狱后发现 iPhone 的个人热点消失了。 iPhone上的个人热点…...

AI 媒人:为什么图形神经网络比 MLP 更好?

一、说明 G拉夫神经网络&#xff08;GNN&#xff09;&#xff01;想象他们是人工智能世界的媒人&#xff0c;通过探索他们的联系&#xff0c;不知疲倦地帮助数据点找到朋友和人气。数字派对上的终极僚机。 现在&#xff0c;为什么这些GNN如此重要&#xff0c;你问&#xff1f;好…...

信息学奥赛一本通 1984:【19CSPJ普及组】纪念品 | 洛谷 P5662 [CSP-J2019] 纪念品

【题目链接】 ybt 1984&#xff1a;【19CSPJ普及组】纪念品 洛谷 P5662 [CSP-J2019] 纪念品 【题目考点】 1. 动态规划&#xff1a;完全背包 【解题思路】 由于小伟每天都可以买卖物品无限次&#xff0c;我们可以假想每天开始时&#xff0c;他把所有的商品都卖出&#xff…...

JVM——JVM参数指南

文章目录 1.概述2.堆内存相关2.1.显式指定堆内存–Xms和-Xmx2.2.显式新生代内存(Young Ceneration)2.3.显示指定永久代/元空间的大小 3.垃圾收集相关3.1.垃圾回收器3.2.GC记录 1.概述 在本篇文章中&#xff0c;你将掌握最常用的 JVM 参数配置。如果对于下面提到了一些概念比如…...

马上七夕到了,用各种编程语言实现10种浪漫表白方式

目录 1. 直接表白&#xff1a;2. 七夕节表白&#xff1a;3. 猜心游戏&#xff1a;4. 浪漫诗句&#xff1a;5. 爱的方程式&#xff1a;6. 爱心Python&#xff1a;7. 心形图案JavaScript 代码&#xff1a;8. 心形并显示表白信息HTML 页面&#xff1a;9. Java七夕快乐&#xff1a;…...

Spring Clould 注册中心 - Eureka,Nacos

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; Eureka 微服务技术栈导学&#xff08;P1、P2&#xff09; 微服务涉及的的知识 认识微服务-服务架构演变&#xff08;P3、P4&#xff09; 总结&#xff1a; 认识微服务-微服务技…...

使用appuploader工具发布证书和描述性文件教程

使用APPuploader工具发布证书和描述性文件教程 之前用AppCan平台开发了一个应用&#xff0c;平台可以同时生成安卓版和苹果版&#xff0c;想着也把这应用上架到App Store试试&#xff0c;于是找同学借了个苹果开发者账号&#xff0c;但没那么简单&#xff0c;还要用到Mac电脑的…...

【面试八股文】每日一题:谈谈你对IO的理解

谈谈你对IO的理解 每日一题-Java核心-谈谈你对对IO的理解【面试八股文】 1.Java基础知识 Java IO&#xff08;Input/Output&#xff09;是Java编程语言中用于处理输入和输出的一组类和接口。它提供了一种在Java程序中读取和写入数据的方法。 Java IO包括两个主要的部分&#x…...

200. 岛屿数量

思路&#xff1a;遍历整个矩阵&#xff0c;对每个格子执行以下操作&#xff1a; 如果格子是陆地&#xff08;‘1’&#xff09;&#xff0c;则将其标记为已访问&#xff08;‘0’&#xff09;&#xff0c;并从当前位置开始进行深度优先搜索&#xff0c;将与当前格子相邻的陆地都…...

【LeetCode】581.最短无序连续子数组

题目 给你一个整数数组 nums &#xff0c;你需要找出一个 连续子数组 &#xff0c;如果对这个子数组进行升序排序&#xff0c;那么整个数组都会变为升序排序。 请你找出符合题意的 最短 子数组&#xff0c;并输出它的长度。 示例 1&#xff1a; 输入&#xff1a;nums [2,6…...

曲面(弧面、柱面)展平(拉直)瓶子标签识别ocr

瓶子或者柱面在做字符识别的时候由于变形&#xff0c;识别效果是很不好的 或者是检测瓶子表面缺陷的时候效果也没有展平的好 下面介绍两个项目&#xff0c;关于曲面&#xff08;弧面、柱面&#xff09;展平&#xff08;拉直&#xff09; 项目一&#xff1a;通过识别曲面的6个点…...

知识继承概述

文章目录 知识继承第一章 知识继承概述1.背景介绍第一页 背景第二页 大模型训练成本示例第三页 知识继承的动机 2.知识继承的主要方法 第二章 基于知识蒸馏的知识继承预页 方法概览 1.知识蒸馏概述第一页 知识蒸馏概述第二页 知识蒸馏第三页 什么是知识第四页 知识蒸馏的核心目…...

深度剖析数据在内存中的存储

目录 一、数据类型介绍 类型的基本归类 1.整形家族 2.浮点数家族 3.构造类型 &#xff08;自定义类型&#xff09; 4.指针类型 5.空类型 二、整形在内存中的存储 1.原码、反码、补码 1.1原码 1.2反码 1.3补码 1.4计算规则 2 .大小端介绍 三、浮点型在内存中的存…...

【ARM Linux 系统稳定性分析入门及渐进10 -- GDB 初始化脚本介绍及使用】

文章目录 gdb 脚本介绍gdb 初始化脚本使用启动 gdb 的时候自动执行脚本gdb运行期间执行命令脚本 gdb 脚本介绍 GDB脚本是一种使用GDB命令语言编写的脚本&#xff0c;可以用来自动化一些常见的调试任务。这些脚本可以直接在GDB中运行&#xff0c;也可以通过GDB的-x参数或source…...

AQS源码解读

文章目录 前言一、AQS是什么&#xff1f;二、解读重点属性statehead、tail 同步变量竞争acquire 同步变量释放 总结 前言 AQS是AbstractQueuedSynchronizer的缩写&#xff0c;也是大神Doug Lea的得意之作。今天我们来进行尽量简化的分析和理解性的代码阅读。 一、AQS是什么&am…...

QT实现天气预报

1. MainWindow类设计的成员变量和方法 public: MainWindow(QWidget* parent nullptr); ~MainWindow(); protected: 形成文本菜单来用来右键关闭窗口 void contextMenuEvent(QContextMenuEvent* event); 鼠标被点击之后此事件被调用 void mousePressEvent(QMouseEv…...

【马蹄集】第二十三周——进位制专题

进位制专题 目录 MT2186 二进制&#xff1f;不同&#xff01;MT2187 excel的烦恼MT2188 单条件和MT2189 三进制计算机1MT2190 三进制计算机2 MT2186 二进制&#xff1f;不同&#xff01; 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...