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

Andriod入门级开发

这学期有个课设,我们组我负责一个手机APP的开发,虽然刚开始说要实现什么智能导航,类似高德地图那种,但最后阉割的只剩一个Socket通信了,因为之前没有接触过(可能之后也不会再接触),记录一下开发中遇到的问题。

1.开发工具:Andriod Studio,主要功能:实现与开发板的Socket通信,具体是手机端收到板子消息按钮变色或者文本框显示对应文字,手机端也会发送消息给板子,让板子跳转用户操作界面,整个就是一个简单的前端,逻辑不需要手机端处理。手机端只负责显示。
2.实现效果:
在这里插入图片描述
在这里插入图片描述

3.一些关键问题和收获:
1)andriod studio 的使用:
感觉还是比较复杂的,前期的一些环境配置有点忘了,按照提示做就可以,主要是手机运行环境的一些配置,然后之后在打包程序安装在手机上出了点问题,需要密钥,按网上指导就可以。
对自带模板的灵活使用:as自带很多模板,比如我开发的这个丑陋的app就是在bottom Navigation Activity这个现成模板的基础上进行开发的。
在这里插入图片描述
之前as排版的Xml文件,下载手机上就会变乱。后面不知不觉就好了,注意这个问题。
2)Socket通信:
这个是这个项目的一个主要工作,其中遇到的第一个问题,怎么创建Socket通信:

class ConnectThread extends Thread {public void run() {try {//新建Socketsocket = new Socket("192.168.4.1", 8086);System.out.println("创建Socket成功");} catch (IOException e) {e.printStackTrace();}}}

Socket的收发信息:注意Socket的收发信息或者说对网络的操作不能直接在主线程进行,一般都需要开子线程。
Socket的收信息:

final byte[] buffer = new byte[1024];//创建接收缓冲区try {inputStream = socket.getInputStream();System.out.println("Socket接收数据成功");} catch (IOException e) {e.printStackTrace();}int len = 0;//数据读出来,并且返回数据的长try {len = inputStream.read(buffer);System.out.println("接收数据大小" + len);} catch (IOException e) {e.printStackTrace();}//BUFFER 内容转为字符串String recvStr = new String(buffer, 0, len);

Socket的发信息:

 //控制子线程开始public void buttonFunc() {// 在主线程中需要发送数据的代码片断前插入// 阻塞主线程,使子线程按照“同步”的方式执行try {System.out.println("线程开始");new Thread(sendthread).start();    // 线程启动new Thread(sendthread).join();     // 线程加入执行队列,主线程被阻塞,等待子线程执行完毕} catch (Exception e) {e.printStackTrace();System.out.println(e.toString());}}// 发送数据子线程final Runnable sendthread = new Runnable() {@Overridepublic void run() {try {System.out.println("发送数据的子线程执行中");try {try {//输出流初始化outputStream = socket.getOutputStream();System.out.println("outputStream创建成功");} catch (IOException e) {e.printStackTrace();}try {//写入数据outputStream.write(sendbuf);outputStream.flush();System.out.println("数据写入成功");} catch (IOException e) {e.printStackTrace();}} catch (Exception e) {e.printStackTrace();}System.out.println("数据发送成功,子线程执行完毕");} catch (Exception e) {e.printStackTrace();System.out.println("子线程:"+ e.toString());}}};

socket的数据解析及数据格式:
收信息需要先转换为string类型,发信息如果要发16进制,byte数组直接写成16进制的形式。

源码:
美食城:

package com.example.parkingassitant2.ui.home;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;import com.example.parkingassitant2.databinding.FragmentHomeBinding;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;public class HomeFragment extends Fragment {private FragmentHomeBinding binding;//发送数据保存byte[] sendbuf = {(byte) 0xaa, (byte) 0xaa,0x03, (byte) 0x12,0x03,0x18, (byte) 0xaa};Socket socket = null;        //定义socketOutputStream  outputStream = null;    //定义输出流(发送)public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {HomeViewModel homeViewModel =new ViewModelProvider(this).get(HomeViewModel.class);binding = FragmentHomeBinding.inflate(inflater, container, false);View root = binding.getRoot();ConnectThread ct;ct = new ConnectThread();ct.start();//江底捞final Button jiangdilao = binding.xiaocaiyuan;//湖底捞按钮final Button hudilao = binding.A2;//河底捞按钮final Button hedilao = binding.B1;//海底捞按钮final Button haidilao = binding.B2;//KFC按钮final Button KFC = binding.C1;//小菜园按钮final Button xiaocaiyuan = binding.C2;//万达影城按钮final Button wanda = binding.D1;//星巴克按钮final Button starbuck = binding.D2;//江底捞按钮监听函数jiangdilao.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x12, 0x03, 0x18, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//湖底捞按钮监听函数hudilao.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x21, 0x03, 0x27, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//河底捞按钮监听函数hedilao.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x22, 0x03, 0x28, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//海底捞按钮监听函数haidilao.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x11, 0x03, 0x17, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//小菜园按钮监听函数xiaocaiyuan.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x13, 0x03, 0x19, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//星巴克按钮监听函数starbuck.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x14, 0x03, 0x1a, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//肯德基按钮监听函数KFC.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x23, 0x03, 0x29, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});//电影院按钮监听函数wanda.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//不同按钮对应不同的数据流sendbuf = new byte[]{(byte) 0xaa, (byte) 0xaa, 0x03, (byte) 0x24, 0x03, 0x2a, (byte) 0xaa};buttonFunc();Toast.makeText(getContext(), "预约成功,请更新停车场信息!", Toast.LENGTH_SHORT).show();}});return root;}class ConnectThread extends Thread {public void run() {try {//两个不同IP地址。网络助手和板子//socket = new Socket("192.168.71.1", 8086);//新建Socketsocket = new Socket("192.168.4.1", 8086);System.out.println("创建Socket成功");} catch (IOException e) {e.printStackTrace();}}}@SuppressLint("SuspiciousIndentation")@Overridepublic void onDestroyView() {super.onDestroyView();binding = null;try {if(socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}//控制子线程开始public void buttonFunc() {// 在主线程中需要发送数据的代码片断前插入// 阻塞主线程,使子线程按照“同步”的方式执行try {System.out.println("线程开始");new Thread(sendthread).start();    // 线程启动new Thread(sendthread).join();     // 线程加入执行队列,主线程被阻塞,等待子线程执行完毕} catch (Exception e) {e.printStackTrace();System.out.println(e.toString());}}// 发送数据子线程final Runnable sendthread = new Runnable() {@Overridepublic void run() {try {System.out.println("发送数据的子线程执行中");try {try {//输出流初始化outputStream = socket.getOutputStream();System.out.println("outputStream创建成功");} catch (IOException e) {e.printStackTrace();}try {//写入数据outputStream.write(sendbuf);outputStream.flush();System.out.println("数据写入成功");} catch (IOException e) {e.printStackTrace();}} catch (Exception e) {e.printStackTrace();}System.out.println("数据发送成功,子线程执行完毕");} catch (Exception e) {e.printStackTrace();System.out.println("子线程:"+ e.toString());}}};
}

停车场:

package com.example.parkingassitant2.ui.dashboard;import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;import com.example.parkingassitant2.databinding.FragmentDashboardBinding;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;public class DashboardFragment extends Fragment {private FragmentDashboardBinding binding;Socket socket = null;		//定义socketOutputStream outputStream = null;    //定义输入流(接收)public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {DashboardViewModel dashboardViewModel = new ViewModelProvider(this).get(DashboardViewModel.class);binding = FragmentDashboardBinding.inflate(inflater, container, false);View root = binding.getRoot();ConnectThread ct;ct = new ConnectThread();ct.start();return root;}class ConnectThread extends Thread{InputStream inputStream=null;	//定义输入流(接收)final Button A1 =binding.A1;final Button A2 = binding.A2;final Button D1 = binding.D1;public void run(){System.out.println(Thread.currentThread().getName()+": Hello");try {//socket = new Socket("192.168.71.1", 8086);socket = new Socket("192.168.4.1", 8086);binding.textView5.setText("连接成功");System.out.println("创建Socket成功");} catch (IOException e) {System.out.println("创建Socket失败");e.printStackTrace();}try{while (true){final byte[] buffer = new byte[1024];//创建接收缓冲区try {inputStream = socket.getInputStream();System.out.println("Socket接收数据成功");} catch (IOException e) {e.printStackTrace();}int len = 0;//数据读出来,并且返回数据的长try {len = inputStream.read(buffer);System.out.println("接收数据大小" + len);} catch (IOException e) {e.printStackTrace();}//BUFFER 内容转为字符串String recvStr = new String(buffer, 0, len);//找到读取开始处,一般为0int stadex = recvStr.indexOf("aaaa");System.out.println("解析数据开始位置" + stadex);int check_3,check_4,check_5,check_6;while(stadex < len){stadex = recvStr.indexOf("aaaa",stadex);int funcType_sta = stadex+4;int funcType_end = stadex+6;if(funcType_end > len || funcType_sta >= len){break;}//位置3是操作类型 02 是显示车牌预约停车场String pos3 = recvStr.substring(funcType_sta,funcType_end);// check_3 = Integer.parseInt(pos3);stadex = funcType_end;//停车预约功能中,位置4是车牌号String pos4 = recvStr.substring(stadex,stadex+2);//check_4 = Integer.parseInt(pos4);stadex += 2;//停车预约功能中,位置5是目的地String pos5 = recvStr.substring(stadex,stadex+2);//check_5 = Integer.parseInt(pos5);stadex += 2;String pos6 = recvStr.substring(stadex,stadex+2);//check_6 = Integer.parseInt(pos6);stadex += 2;//if( check_6 != check_3+check_4+check_5) break;stadex += 2;System.out.println("解析数据包" + "aaaa" + pos3 + pos4 + pos5 + pos6 + "aa");System.out.println("操作类型指示值:" + pos3);switch(pos3){case "01": {System.out.println("操作类型为欢迎车牌进站");String showText = null;switch (pos4) {case "01":showText = "欢迎京A00001";break;case "02":showText = "欢迎青ASB520";break;case "03":showText = "欢迎皖A66666";break;case "04":showText = "欢迎宁E88888";break;default:break;}binding.textView5.setText(showText);break;}case "04": {System.out.println("操作类型为停车预约");String showText = null;switch (pos4) {case "01":showText = "京A00001";break;case "02":showText = "青ASB520";break;case "03":showText = "皖A66666";break;case "04":showText = "宁E88888";break;default:break;}String address = null;switch (pos5){case "11":address = "海底捞";break;case "12":address = "江底捞";break;case "13":address = "小菜园";break;case "14":address = "星巴克";break;case "21":address = "湖底捞";break;case "22":address = "河底捞";break;case "23":address = "肯德基";break;case "24":address = "电影院";break;case "a1":address = "A1";break;case "a2":address = "A2";break;case "d1":address = "D1";break;default:break;}binding.textView5.setText(showText+"车主预约车位:" + address);break;}case "03": {System.out.println("操作类型为车位状态变更");switch (pos4) {case "a1": {if (pos5.equals("00")) {binding.A1.setBackgroundColor(Color.parseColor("#00FF00"));} else if (pos5.equals("01")) {binding.A1.setBackgroundColor(Color.parseColor("#FF0000"));} else if (pos5.equals("02")) {binding.A1.setBackgroundColor(Color.parseColor("#FFFF00"));}break;}case "a2": {System.out.println("pos5: ");System.out.println(pos5);if (pos5.equals("00")) {binding.A2.setBackgroundColor(Color.parseColor("#00FF00"));} else if (pos5.equals("01")) {binding.A2.setBackgroundColor(Color.parseColor("#FF0000"));} else if (pos5.equals("02")) {binding.A2.setBackgroundColor(Color.parseColor("#FFFF00"));}break;}case "d1": {if (pos5.equals("00")) {binding.D1.setBackgroundColor(Color.parseColor("#00FF00"));} else if (pos5.equals("01")) {binding.D1.setBackgroundColor(Color.parseColor("#FF0000"));} else if (pos5.equals("02")) {binding.D1.setBackgroundColor(Color.parseColor("#FFFF00"));}break;}default:break;}}default:break;}}}} catch (Exception ex) {ex.printStackTrace();}}}@SuppressLint("SuspiciousIndentation")@Overridepublic void onDestroyView() {super.onDestroyView();try {if(socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}binding = null;}
}

相关文章:

Andriod入门级开发

这学期有个课设&#xff0c;我们组我负责一个手机APP的开发&#xff0c;虽然刚开始说要实现什么智能导航&#xff0c;类似高德地图那种&#xff0c;但最后阉割的只剩一个Socket通信了&#xff0c;因为之前没有接触过&#xff08;可能之后也不会再接触&#xff09;&#xff0c;记…...

DCL 数据控制语言

1、简介 DCL英文全称是Data Control Language(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限。 2、管理用户 2.1 查询用户 select * from mysql.user;查询的结果如下: 其中 Host代表当前用户访问的主机, 如果为localhost, 仅代表只能够在当前本机访问…...

全网超详细的下载与安装VMware虚拟机以及为什么要安装VMware虚拟机

文章目录1. 文章引言2. 下载VMware3. 安装VMware1. 文章引言 我们使用最多的系统是windows系统&#xff0c;因为&#xff0c;国内电脑厂商的操作系统(os)基本是windows系统&#xff0c;比如华为、联想、华硕等电脑。 但线上的服务器大多是Linux系统&#xff0c;而我们经常使用…...

Python获取zabbix问题触发器

背景&#xff1a;阿里云的ECS服务器因为阿里云升级插件&#xff0c;导致安全防护程序重启&#xff0c;产生不同的端口。导致低自动发现注册的端口 大量报警。 解决&#xff1a;杀掉关于因为非业务 变更的端口检测的触发器。 相关文档&#xff1a; Zabbix监控之主机端口监控自…...

原型链污染

目录 前置知识 原型对象 prototype和__proto__的区别 原型链概念 原型链的继承 原型 链污染 原型链污染原理 javascript中可能会存在原型链污染的危险函数 原型链污染的实际应用 JavaScript中可以触发弹窗的函数 前置知识 原型对象 在JavaScript中&#xff0c;每个函…...

ClickHouse详解

一、概念ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。OLAP场景的关键特征绝大多数是读请求数据以相当大的批次(> 1000行)更新&#xff0c;而不是单行更新;或者根本没有更新。已添加到数据库的数据不能修改。对于读取&#xff0c;从数据库中提取相当多的…...

02_Docker 安装

02_Docker 安装 文章目录02_Docker 安装2.1 安装 Docker 的先决条件2.2 在 Ubuntu 和 Debain 中安装 Docker2.2.1 检查前提条件1. 内核2.检查 Device Manager2.2 安装 DockerDocker 支持非常多的Linux平台&#xff0c;包括Ubuntu和RHEL&#xff0c;除此之外&#xff0c;Docker还…...

K8S集群将Docker切换到Containerd

文章目录1. 开启节点维护1.1 将节点设置成不可调度1.2 驱逐节点上的 Pod1.3 停止相关服务2. 升级到 containerd2.1 安装 containerd2.2 调整 containerd 配置2.3 修改 kubelet 启动配置参数3. 重启节点服务4. 验证升级后的节点5. 容器管理工具5.1 容器管理命令行工具对比5.2 cr…...

Kubernetes03:kubernetes 功能和架构

2.1 概述 Kubernetes 是一个轻便的和可扩展的开源平台&#xff0c;用于管理容器化应用和服务。通过 Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中&#xff0c;会将组成应用的容 器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环…...

LabVIEW中CPU和内存使用情况在NI分布式系统管理器中不可见

LabVIEW中CPU和内存使用情况在NI分布式系统管理器中不可见想使用NI分布式系统管理器监测网络连接实时控制器的CPU和内存使用情况。从左侧窗口的树中选择了感兴趣的实时目标&#xff0c;然后通过选择视图自动视图来确保启用自动查看。希望看到CPU/内存选项卡&#xff0c;但它有显…...

buu [NPUCTF2020]Classical Cipher 1

题目描述&#xff1a; 题目分析&#xff1a; 首先输入密码 {gsv_pvb_rh_zgyzhs} 后&#xff0c;得到&#xff1a;可以得知密码是错误的&#xff0c;再看看密码 {gsv_pvb_rh_zgyzhs} &#xff0c;排列无序&#xff0c;那么尝试用凯撒与栅栏解密&#xff0c;发现还是解不出&…...

分享96个HTML体育竞技模板,总有一款适合您

分享96个HTML体育竞技模板&#xff0c;总有一款适合您 96个HTML体育竞技模板下载链接&#xff1a;https://pan.baidu.com/s/1k2vJUlbd2Boduuqqa0EWMA?pwdj8ji 提取码&#xff1a;j8ji Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 北京奥运火炬PSD模板 奥运…...

Python pandas「原有或者新建」Excel中「追加新或者新建」sheet

1.pandas原有Excel中追加新sheet 使用Pandas库&#xff0c;我们可以轻松将数据追加到现有的Excel工作簿中的新工作表中。以下是追加新工作表的简单步骤&#xff1a; 读取现有的Excel文件 使用Pandas库中的read_excel()函数读取现有的Excel文件。指定Excel文件的路径和文件名&a…...

程序员必备的软技能- CPU“没有灵魂的躯体”

引言 先引用一段比较有意思的论述&#xff1a; 现实中每个人是由两部分构成&#xff0c;灵魂和躯体&#xff0c;灵魂依附于躯体游走于世间&#xff0c;现实中我们面对的每个人其实面对的是其灵魂而非肉体&#xff0c;肉体不过是表象而已。 灵魂本性乃一恶物&#xff0c;寄生于…...

基于微信小程序的青少年生理健康知识小助手

基于微信小程序的青少年生理健康知识小助手 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目…...

【scl】博图程序的导入和导出

导入或者导出博图文件的方法&#xff08;也叫移植文件&#xff09; 目录 前言 ​编辑 ​编辑 前言 本篇文章主要写一下关于博图文件的导入和导出&#xff0c;具体要怎么样才能将写好的程序或者块移植到其他地方&#xff0c;下面我们一起来看&#xff01; 一、程序块的导入和导…...

【C语言】指针进阶

目录 一、字符指针 二、指针数组 三、数组指针 四、数组指针的使用 五、函数指针数组 六、指向函数指针数组的指针 七、回调函数 我们知道了指针的概念&#xff1a; 1. 指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 2. 指针的大小是…...

18:CTK 总结篇(FAQ)

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 经过了几个月的艰苦奋战,终于到了最后一节啦,是不是和我一样,心里有点儿小激动! 回顾之前的章节,从初级 -> 进阶 -> 高级,我们针对 CTK 做了详细的分类讲解。希望通过这些知识,大家能对模块化…...

概论_第7章_参数估计_真题__求置信区间

真题 2014.10 第30题 测量某物体的质量9次&#xff0c; 测得平均值 x‾15.4\overline x 15.4x15.4 g, 已知测量数据 XXX ~ N(μ,0.09)N(\mu, 0.09)N(μ,0.09) (1) 求该物体质量的置信度为0.95 的置信区间&#xff1b; &#xff08;2&#xff09;为了使置信度为0.95 的置信区间…...

Go 1.21的2个语言变化

语言行为变化 Go 1.20已经于今年2月份发布&#xff0c;Go 1.21也不远了&#xff0c;我们来先堵为快&#xff0c;看看Go 1.21版本里几个有趣的变化。 文末附送2道面试题。 panic(nil) func main() {defer func() {print(recover() nil)}()panic(nil) }大家先想一想这段代码…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...