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
英文地址,請注明出處:http://en.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;存在單點…