Android 开发 - Service、Camera、Layout Design 自定义设备类型和大小

一、Service 启动

1、基本介绍
(1)startService()
  1. 其他组件通过调用 startService() 启动 Service 后,Service 可在后台无限期运行,即使启动 Service 的组件被销毁也不受影响,一般情况下 startService() 是执行单一操作,不会将执行结果返回给调用者,例如,下载文件或者上传文件,操作完成后会自动停止

  2. 这种方式允许多个组件同时对同一 Service 进行 startService() 操作,但只要有其中有一个组件调用了 stopSelf() 或 stopService(), 该 Service 就会被销毁

(2)bindService()
  1. 组件通过调用 bindService() 启动 Service ,Service 就处于绑定状态,可让调用者与 Service 进行发送请求和返回结果的操作,还可以进行进程间的通信

  2. 一个组件对该 Service 进行绑定,那该 Service 就不会销毁,若多个组件同时对一个 Service 进行绑定,只有全部绑定的该 Service 的组件都解绑后,Service 才会销毁

2、注意事项
  1. 虽然 Service 是在后台运行,但其实还是在主线程中进行所有的操作,Service 启动时除非单独进行了定义,否则没有单独开启线程且都运行在主线程中

  2. 任何能阻塞主线程的操作,应该在 Service 中单独开启新线程来进行操作,否则很容易出现 ANR

4、Service 生命周期
  • Service 同样有生命周期回调方法
  1. startService 方式的方法回调:onCreate() -> onStartCommand() -> onDestroy()

  2. bindService 方式的方法回调:onCreate() -> onBind() -> onUnbind() -> onDestroy()


二、Service 使用

1、startService
(1)Service
  • MyService.java
package com.my.other.service;import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;import androidx.annotation.Nullable;public class MyService extends Service {private static final String TAG = "MyService";@Overridepublic void onCreate() {super.onCreate();Log.i(TAG, "------------------------------ onCreate");}@Overridepublic void onStart(Intent intent, int startId) {super.onStart(intent, startId);Log.i(TAG, "------------------------------ onStart");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.i(TAG, "------------------------------ onStartCommand");return super.onStartCommand(intent, flags, startId);}@Nullable@Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, "------------------------------ onBind");return null;}@Overridepublic boolean onUnbind(Intent intent) {Log.i(TAG, "------------------------------ onUnbind");return super.onUnbind(intent);}@Overridepublic void onDestroy() {super.onDestroy();Log.i(TAG, "------------------------------ onDestroy");}
}
(2)AndroidManifest
<application ...>  <service android:name=".service.MyService" />...  
</application>
(3)Activity Layout
  • activity_start_service.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".StartServiceActivity"><Buttonandroid:id="@+id/btn_start_service"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="开启服务"android:onClick="startService"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn_stop_service"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="停止服务"android:onClick="stopService"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_start_service" />
</androidx.constraintlayout.widget.ConstraintLayout>
(4)Activity Code
  • StartServiceActivity.java
package com.my.other;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.view.View;import com.my.other.service.MyService;public class StartServiceActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_start_service);}public void startService(View view) {startService(new Intent(this, MyService.class));}public void stopService(View view) {stopService(new Intent(this, MyService.class));}
}
(5)Test
  1. 点击【开启服务】按钮,输出结果
I/MyService: ------------------------------ onCreate
I/MyService: ------------------------------ onStartCommand
I/MyService: ------------------------------ onStart
  1. 点击【停止服务】按钮,输出结果
I/MyService: ------------------------------ onDestroy
2、BindService
(1)Activity Layout
  • activity_bind_service.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".BindServiceActivity"><Buttonandroid:id="@+id/btn_my_bind_service"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="绑定服务"android:onClick="myBindService"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/btn_my_unbind_service"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="40dp"android:text="解绑服务"android:onClick="myUnbindService"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_my_bind_service" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
  • BindServiceActivity.java
package com.my.other;import androidx.appcompat.app.AppCompatActivity;import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;import com.my.other.service.MyService;public class BindServiceActivity extends AppCompatActivity {private static final String TAG = "BindServiceActivity";// BindServiceActivity 与 MyService 的桥梁private ServiceConnection serviceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {Log.i(TAG, "------------------------------ onServiceConnected");}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.i(TAG, "------------------------------ onServiceDisconnected");}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_bind_service);}public void myBindService(View view) {bindService(new Intent(this, MyService.class), serviceConnection, Context.BIND_AUTO_CREATE);}public void myUnbindService(View view) {unbindService(serviceConnection);}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(serviceConnection);}
}
(3)Test
  1. 点击【绑定服务】按钮,输出结果
I/MyService: ------------------------------ onCreate
I/MyService: ------------------------------ onBind
  1. 点击【解绑服务】按钮,输出结果
I/MyService: ------------------------------ onUnbind
I/MyService: ------------------------------ onDestroy

三、Camera 使用

1、基本使用
(1)Activity Layout
  • activity_camera_test.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#E0F7FA"tools:context=".CameraTestActivity"><SurfaceViewandroid:id="@+id/sv"android:layout_width="300dp"android:layout_height="300dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
  • CameraTestActivity.java
package com.my.camera;import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;import java.io.IOException;
import java.util.List;@SuppressWarnings("all")
public class CameraTestActivity extends AppCompatActivity {public static final String TAG = CameraTestActivity.class.getSimpleName();private Camera camera;private SurfaceView sv;private SurfaceHolder surfaceHolder;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_camera_test);// 保持屏幕常亮getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);sv = findViewById(R.id.sv);surfaceHolder = sv.getHolder();surfaceHolder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {Log.i(TAG, "++++++++++++++++++++++++++++++ surfaceCreated");openCamera();}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {Log.i(TAG, "++++++++++++++++++++++++++++++ surfaceChanged");if (camera == null) return;Camera.Parameters parameters = camera.getParameters();List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();Camera.Size previewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height);parameters.setPreviewSize(previewSize.width, previewSize.height);camera.setParameters(parameters);camera.startPreview();}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {Log.i(TAG, "++++++++++++++++++++++++++++++ surfaceDestroyed");}});}private void openCamera() {try {if (camera != null) return;camera = Camera.open();camera.setPreviewDisplay(surfaceHolder);camera.setPreviewCallback(new Camera.PreviewCallback() {@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {// 这里可以处理预览帧数据Log.i(TAG, "得到预览帧数据 ------------------------------ size:" + data.length);}});camera.setDisplayOrientation(90);} catch (IOException e) {e.printStackTrace();releaseCamera();}}private void releaseCamera() {if (camera != null) {camera.stopPreview();camera.release();camera = null;}}/*** 根据 SurfaceView 的尺寸和相机支持的预览尺寸来选择最优的预览尺寸** @param sizes 相机支持的预览尺寸列表* @param w     SurfaceView 的宽度* @param h     SurfaceView 的高度* @return 最优的预览尺寸,如果没有合适的尺寸则返回 null*/private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {if (sizes == null) return null;final double ASPECT_TOLERANCE = 0.1;double targetRatio = (double) h / w;Camera.Size optimalSize = null;double minDiff = Double.MAX_VALUE;int targetHeight = h;// 遍历所有支持的预览尺寸for (Camera.Size size : sizes) {// 检查宽高比是否接近目标宽高比double ratio = (double) size.width / size.height;if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;// 计算当前尺寸与目标尺寸的宽度差异// 如果差异小于当前最小差异,则更新最优尺寸和最小差异if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}// 如果找不到接近目标宽高比的尺寸,则选择最接近目标高度的尺寸if (optimalSize == null) {minDiff = Double.MAX_VALUE;for (Camera.Size size : sizes) {if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}}return optimalSize;}
}
  • 输出结果
I/CameraTestActivity: ++++++++++++++++++++++++++++++ surfaceCreated
I/CameraTestActivity: ++++++++++++++++++++++++++++++ surfaceChanged
I/CameraTestActivity: 得到预览帧数据 ------------------------------ size:1775616
I/CameraTestActivity: 得到预览帧数据 ------------------------------ size:1775616
I/CameraTestActivity: 得到预览帧数据 ------------------------------ size:1775616
2、优化使用
(1)Activity Layout
  • activity_camera_callback_buffer.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#E0F7FA"tools:context=".CameraCallbackBufferActivity"><SurfaceViewandroid:id="@+id/sv"android:layout_width="300dp"android:layout_height="300dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(2)Activity Code
  • CameraCallbackBufferActivity.java
package com.my.camera;import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;@SuppressWarnings("all")
public class CameraCallbackBufferActivity extends AppCompatActivity {public static final String TAG = CameraCallbackBufferActivity.class.getSimpleName();private Camera camera;private SurfaceView sv;private SurfaceHolder surfaceHolder;private List<byte[]> previewBuffers;private int backCameraId;private Camera.CameraInfo backCameraInfo;private int frontCameraId;private Camera.CameraInfo frontCameraInfo;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_camera_callback_buffer);getCameraInfo();sv = findViewById(R.id.sv);surfaceHolder = sv.getHolder();surfaceHolder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {openCamera();}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {if (camera == null) return;camera.startPreview();}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {}});}private void getCameraInfo() {int numberOfCameras = Camera.getNumberOfCameras();// 获取摄像头个数Log.i(TAG, "------------------------------ 摄像头个数:" + numberOfCameras);for (int cameraId = 0; cameraId < numberOfCameras; cameraId++) {Camera.CameraInfo cameraInfo = new Camera.CameraInfo();Camera.getCameraInfo(cameraId, cameraInfo);if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {Log.i(TAG, "------------------------------ 后置摄像头,cameraId 为:" + cameraId);backCameraId = cameraId;backCameraInfo = cameraInfo;} else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {Log.i(TAG, "------------------------------ 前置摄像头,cameraId 为:" + cameraId);frontCameraId = cameraId;frontCameraInfo = cameraInfo;} else {Log.i(TAG, "------------------------------ 其他摄像头,cameraId 为:" + cameraId);}Log.i(TAG, "---------- facing 为:" + cameraInfo.facing);Log.i(TAG, "---------- orientation 为:" + cameraInfo.orientation);Log.i(TAG, "---------- canDisableShutterSound 为:" + cameraInfo.canDisableShutterSound);}}private void openCamera() {try {if (camera != null) return;camera = Camera.open(frontCameraId);if (camera == null) return;Camera.Parameters parameters = camera.getParameters();List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();Camera.Size optimalPreviewSize = getOptimalPreviewSize(supportedPreviewSizes, sv.getWidth(), sv.getHeight());parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);parameters.setPreviewFormat(ImageFormat.YV12);camera.setParameters(parameters);int bufferSize = optimalPreviewSize.width * optimalPreviewSize.height * ImageFormat.getBitsPerPixel(ImageFormat.YV12) / 8;previewBuffers = new ArrayList<>();for (int i = 0; i < 3; i++) { // 通常需要 3 个缓冲区来避免丢失帧byte[] buffer = new byte[bufferSize];previewBuffers.add(buffer);}camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {// 处理预览帧数据Camera.Parameters parameters = camera.getParameters();Camera.Size size = parameters.getPreviewSize();if (size != null) processFrame(data, size.width, size.height);// 回收缓冲区供相机再次使用camera.addCallbackBuffer(data);}});camera.addCallbackBuffer(previewBuffers.get(0));camera.addCallbackBuffer(previewBuffers.get(1));camera.addCallbackBuffer(previewBuffers.get(2));camera.setPreviewDisplay(surfaceHolder);camera.startPreview();} catch (IOException e) {e.printStackTrace();releaseCamera();}}private void releaseCamera() {if (camera != null) {camera.stopPreview();camera.release();camera = null;}}/*** 根据 SurfaceView 的尺寸和相机支持的预览尺寸来选择最优的预览尺寸** @param sizes 相机支持的预览尺寸列表* @param w     SurfaceView 的宽度* @param h     SurfaceView 的高度* @return 最优的预览尺寸,如果没有合适的尺寸则返回 null*/private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {if (sizes == null) return null;final double ASPECT_TOLERANCE = 0.1;double targetRatio = (double) h / w;Camera.Size optimalSize = null;double minDiff = Double.MAX_VALUE;int targetHeight = h;// 遍历所有支持的预览尺寸for (Camera.Size size : sizes) {// 检查宽高比是否接近目标宽高比double ratio = (double) size.width / size.height;if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;// 计算当前尺寸与目标尺寸的宽度差异// 如果差异小于当前最小差异,则更新最优尺寸和最小差异if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}// 如果找不到接近目标宽高比的尺寸,则选择最接近目标高度的尺寸if (optimalSize == null) {minDiff = Double.MAX_VALUE;for (Camera.Size size : sizes) {if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}}return optimalSize;}private void processFrame(byte[] data, int width, int height) {// 在这里处理预览帧数据,例如转换为位图、进行图像处理等Log.i(TAG, "------------------------------ Received preview frame: " + data.length + " bytes");}@Overrideprotected void onResume() {super.onResume();openCamera();}@Overrideprotected void onPause() {super.onPause();releaseCamera();}
}

四、Layout Design 自定义设备类型和大小

  1. 创建自定义虚拟设备
  1. 新建硬件配置文件,主要配置屏幕大小和分辨率
  1. 选择硬件配置文件,完成自定义虚拟设备的创建
  1. 使用自定义虚拟设备

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/92214.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qwen Image:开源中文渲染SOTA,重塑文生图技术边界

1. Qwen Image的技术定位与行业痛点1.1 文本渲染&#xff1a;文生图领域的长期技术瓶颈传统文生图模型在图像美学与真实感优化上已取得显著进展&#xff0c;但多语言文本渲染始终是行业难以突破的瓶颈。主流模型在处理中文等非字母语言时&#xff0c;常出现字符断裂、布局错位、…

Docker入门教程:在腾讯云轻量服务器上部署你的第一个容器化应用 (2025)

更多云服务器知识&#xff0c;尽在hostol.com“在我电脑上明明是好的啊&#xff01;”这句话&#xff0c;是不是堪称程序员“甩锅”排行榜第一名的金句&#xff1f;当你辛辛苦苦开发完一个应用&#xff0c;把它交给同事或者部署到服务器上时&#xff0c;却发现因为它依赖的某个…

DevOps平台结合Gradle实现打包流水线

在现代软件开发中,持续集成与持续交付(CI/CD)已成为团队提速、降本增效的核心实践。Gradle作为强大的自动化构建工具,常被用于Android与Java项目的构建打包任务。而将Gradle集成进企业的DevOps平台中,不仅可以标准化构建过程,还能自动化打包、测试、发布的全流程,大幅提…

Node.js 操作 MySQL

目录 一、什么是 MySQL&#xff1f; 二、MySQL 的功能概览 三、MySQL 的安装与启动 安装 MySQL 启动服务 四、Node.js 如何连接 MySQL&#xff1f; 使用 mysql2 模块&#xff08;推荐&#xff09; 建立连接 五、创建数据表和插入数据&#xff08;SQL 初始化&#xff09…

解锁高效敏捷:2025年Scrum项目管理工具的核心应用解析

一、为什么Scrum团队需要专业项目管理工具&#xff1f;在敏捷开发实践中&#xff0c;Scrum框架虽然提供了基础的工作流程&#xff0c;但缺乏对任务细粒度管理的支持。传统白板或简单看板工具往往无法满足现代敏捷团队的需求&#xff0c;导致&#xff1a;冲刺规划混乱&#xff1…

途游大数据面试题及参考答案

Java 的反射机制是什么?主要应用在哪些场景? Java的反射机制是指程序在运行时,能够获取自身类的信息(如类名、属性、方法、构造器等),并动态操作这些信息的能力。正常情况下,Java代码编译时类型已确定,而反射打破了这种编译期约束,让程序在运行时灵活操作类和对象。 …

贪心+矩阵算法

贪心算法贪心的本质是&#xff1a;选择每一阶段的局部最优&#xff0c;从而达到全局最优做题的时候&#xff0c;只要想清楚 局部最优 是什么&#xff0c;如果推导出全局最优&#xff0c;其实就够了。买卖股票的最佳实际思路&#xff1a;如果第i天卖出股票&#xff0c;则最大利润…

STM32U5 周期性异常复位问题分析

关键字&#xff1a; Option Bytes, IDWG 1. 问题背景 客户反馈使用 NUCLEO_STM32U575 进行评估时&#xff0c;发现板子烧录完程序后&#xff0c;能看到指示程序运行的 LED 灯正常点亮&#xff0c;但是程序跑不起来。仔细观察 LED 指示灯&#xff0c;并不是常亮而是出现周期性…

RedisBloom使用

安装RedisBloom模块&#xff0c;从git获取对应的原码&#xff0c;make生成.so文件&#xff0c;挂载.so文件&#xff0c;启动redis docker run --name test-redis -v /iothub/test-redis/data:/data -v /iothub/test-redis/modules:/modules -p 6378:6379 -d redis:4.0.10 redis…

ADC、Flash、SPI、watchdog

ADCADC(Analog-to-Digital Converter), 即模拟信号 - 数字信号转换器在STM32F103C8T6中, 同样具有ADC功能.以我们的芯片为例, 也存在2个片上外设ADC, 即ADC1和ADC2, 这两个ADC片上外设都挂载在APB2总线上.我们的ADC片上外设, 是一种具有12位逐次逼近型ADC,ADC转换的本质是不断的…

冷库设备远程监控物联网+省电节能解决方案

随着生鲜电商、医药冷链、跨境物流等行业的爆发式增长&#xff0c;我国冷库容量激增&#xff0c;但传统冷库管理模式正面临严峻挑战。据统计&#xff0c;国内冷链运输损耗率高达12%-15%&#xff0c;其中因温度失控导致的货损占比超60%。在某医药企业冷库事故中&#xff0c;因制…

如何开发一个运行在windows系统服务器上的服务

第一步&#xff1a;vs2022创建一个windows服务项目第二步&#xff1a;从工具箱拖拽出一个timer第三步&#xff1a;按下图所示进入&#xff0c;开始编辑业务逻辑下面给个例子using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; …

本地组策略编辑器无法打开(gpedit.msc命令异常)

一、本地组策略编辑器打开方式1、直接搜索打开&#xff08;1&#xff09;在搜索栏中直接输入以下内容进行搜索本地组策略编辑器&#xff08;2&#xff09;搜索到后直接点击打开即可&#xff08;但是一部分同志无法搜索到&#xff0c;搜索到的内容基本都是网页信息而非本地系统的…

kafka部署集群模式

Kafka部署&#xff08;3.7&#xff09; 生产环境推荐的kafka部署方式为operator方式部署&#xff0c;Strimzi是目前最主流的operator方案。集群数据量较小的话&#xff0c;可以采用NFS共享存储&#xff0c;数据量较大的话可使用local pv存储 部署operator operator部署方式为he…

C语言中级_动态内存分配、指针和常量、各种指针类型、指针和数组、函数指针

0、前言&#xff1a; 动态内存分配是一个重要概念&#xff0c;要和静态数组对比着学习&#xff1b;指针和数组搭配在一起&#xff0c;让指针理解的难度上了一个台阶&#xff0c;尤其是二维数组搭配指针&#xff0c;要获取数组的值&#xff0c;什么时候“取地址”&#xff0c;什…

单变量单步时序预测:CNN-GRU卷积神经网络结合门控循环单元

目录预测效果1. **CNN-GRU的基本原理**2. **应用场景**3. **模型结构与实现**4. **优势与挑战**5. **相关研究与实现**6. **未来发展方向**结论代码设计预测效果 CNN-GRU卷积神经网络结合门控循环单元是一种结合了卷积神经网络&#xff08;CNN&#xff09;和门控循环单元&#…

MonoFusion 与 Genie 3

卡内基梅隆大学的研究者发明了一种叫 MonoFusion 的新技术&#xff0c;它能用很少的普通相机&#xff08;比如4个&#xff09;&#xff0c;就能拍出像电影特效一样细腻流畅的动态3D场景&#xff08;4D重建&#xff09;&#xff0c;比如弹钢琴、修自行车这种复杂动作&#xff0c…

kubernets命令行创建Token并附加权限给dashboard控制台登录

1、创建登录token kubectl create token default -n graph-node-test dgjeojrgopejgeropjgpsdjgerjglsdjfsjogjeojgeorjgortlfhj4yu493460uwperg3wef;lsj2y3r934tnrhifrlfe9t4h5tlhobdrmlgw485tw4yp653ut9ogogjerolj4w9erjgotj3fgjletyj49yr20o359truyo5u6908430jt5grjsdtgj49…

什么是SpringBoot

题目详细答案Spring Boot 是由 Pivotal 团队提供的一个基于 Spring 框架的项目&#xff0c;它旨在简化 Spring 应用的开发和部署。Spring Boot 通过提供一系列的约定和开箱即用的功能&#xff0c;使得开发者可以更快地构建独立的、生产级的 Spring 应用程序&#xff0c;而无需进…

从零开始设计一个分布式KV存储:基于Raft的协程化实现

从零开始设计一个分布式KV存储&#xff1a;基于Raft的协程化实现 本文将以一个最小可运行的分布式KV系统为例&#xff0c;带你拆解如何用C、Raft算法和协程模型构建高可用的Key-Value存储。 一、为什么需要分布式KV&#xff1f; 单机KV&#xff08;如Redis&#xff09;存在单点…