安卓CameraX的使用
如果要在安卓应用中操作相机,有三个库可以选:
- Camera(已废弃):Camera是安卓最早的包,目前已废弃,在Android 5.0(API 级别 21)的设备上操作相机可以选择该包,保证兼容性;
- Camera2:Camera2在Android 5.0(API 级别 21)开始提供,用于替代Camera,相比Camera,在性能、灵活性等方面有优势,但是使用起来更复杂;
- CameraX:CameraX是对Camera2的封装,是Jetpack的一个库,支持Android 5.0(API 级别 21)及更高版本。CameraX降低了操作相机的难度,大多数情况下,使用CameraX已足以完成需求,建议使用CameraX。
注:Jetpack是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种Android版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。
谷歌的文档只提供了Kotlin的代码示例,根据Kotlin的代码示例和文档,本文提供Java的实现。
1. CameraX常见用例
您可以使用CameraX,借助名为“用例”的抽象概念与设备的相机进行交互。提供的用例如下:
- 预览(Preview):在屏幕上查看相机画面;
- 图片分析(ImageAnalysis):逐帧处理相机捕获到的每一帧画面;
- 图片拍摄(ImageCapture):拍照;
- 视频拍摄(VideoCapture):拍视频(和音频)。
CameraX允许同时使用Preview、VideoCapture、ImageAnalysis和ImageCapture各一个实例。此外:
- 每个用例都可以单独使用。例如,应用可以在不使用预览的情况下录制视频;
- 启用扩展后,只能保证能够使用ImageCapture和Preview的组合。根据OEM实现情况,可能无法同时添加ImageAnalysis;无法为VideoCapture用例启用扩展。如需了解详情,请参阅扩展参考文档;
- 对于某些相机而言,在较低分辨率模式下可以支持的组合,在较高的分辨率下将无法支持,这具体取决于相机的功能;
- 在相机硬件级别为FULL或更低的设备上,组合使用Preview、VideoCapture和ImageCapture或ImageAnalysis可能会迫使CameraX为Preview和VideoCapture复制相机的PRIV数据流。这种重复(称为数据流共享)可让您同时使用这些功能,但代价是增加了处理需求。因此,您可能会遇到略长的延迟时间和缩短的电池续航时间。
2. 代码实现
在build.gradle中添加相关依赖:
// camerax
def camerax_version = "1.3.0"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
implementation "androidx.camera:camera-view:${camerax_version}"
implementation "androidx.camera:camera-video:${camerax_version}"
// 扩展,本文代码未使用
// implementation "androidx.camera:camera-extensions:${camerax_version}"
在AndroidManifest.xml添加相关权限:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
添加布局文件activity_camerax_preview.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"><androidx.camera.view.PreviewViewandroid:id="@+id/camerax_preview_view"android:layout_width="match_parent"android:layout_height="match_parent" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"><Buttonandroid:id="@+id/camerax_flash"android:layout_width="110dp"android:layout_height="70dp"android:layout_marginStart="10dp"android:layout_marginTop="5dp"android:layout_marginEnd="10dp"android:layout_marginBottom="5dp"android:text="开灯" /><Buttonandroid:id="@+id/camerax_switch_camera"android:layout_width="110dp"android:layout_height="70dp"android:layout_marginStart="10dp"android:layout_marginTop="5dp"android:layout_marginEnd="10dp"android:layout_marginBottom="5dp"android:text="切换摄像头" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"><Buttonandroid:id="@+id/camerax_image_capture_button"android:layout_width="110dp"android:layout_height="70dp"android:layout_marginStart="10dp"android:layout_marginTop="5dp"android:layout_marginEnd="10dp"android:layout_marginBottom="5dp"android:text="拍照" /><Buttonandroid:id="@+id/camerax_video_capture_button"android:layout_width="110dp"android:layout_height="70dp"android:layout_marginStart="10dp"android:layout_marginTop="5dp"android:layout_marginEnd="10dp"android:layout_marginBottom="5dp"android:text="开始录制" /><Buttonandroid:id="@+id/camerax_video_capture_pause_button"android:layout_width="110dp"android:layout_height="70dp"android:layout_marginStart="10dp"android:layout_marginTop="5dp"android:layout_marginEnd="10dp"android:layout_marginBottom="5dp"android:text="暂停录制"android:visibility="gone" /></LinearLayout></LinearLayout></RelativeLayout>
</RelativeLayout>
activity类:
package org.tao.hetools.activities;import android.Manifest;
import android.content.ContentValues;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.core.TorchState;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.video.MediaStoreOutputOptions;
import androidx.camera.video.Quality;
import androidx.camera.video.QualitySelector;
import androidx.camera.video.Recorder;
import androidx.camera.video.Recording;
import androidx.camera.video.VideoCapture;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;import com.google.common.util.concurrent.ListenableFuture;import org.tao.hetools.R;
import org.tao.hetools.utils.PermissionUtils;import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;public class CameraxPreviewActivity extends ComponentActivity {private static final String TAG = "CameraxPreviewActivity";private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmssSSS");private static final Size SIZE = new Size(1080, 1920);private static final List<CameraSelector> CAMERAS = Arrays.asList(CameraSelector.DEFAULT_BACK_CAMERA,CameraSelector.DEFAULT_FRONT_CAMERA);private static final String START_RECORD = "开始录制";private static final String STOP_RECORD = "结束录制";private static final String PAUSE_RECORD = "暂停录制";private static final String RESUME_RECORD = "恢复录制";private PreviewView previewView;private Executor executor;private Preview preview;private ImageAnalysis imageAnalysis;private ImageCapture imageCapture;private VideoCapture<Recorder> videoCapture;private Recording videoRecording;private ProcessCameraProvider cameraProvider;private Camera camera;private boolean isRecordingStart = false;private boolean isRecordingPause = false;private int cameraIndex = 0;private Button flashButton;private Button pauseResumeVideoButton;private Button startShopVideoButton;private Button switchCameraButton;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.activity_camerax_preview);PermissionUtils.checkPermission(this, Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE);previewView = findViewById(R.id.camerax_preview_view);executor = ContextCompat.getMainExecutor(this);initCamerax();initButton();}private void initCamerax() {// 可以将相机生命周期绑定到activity,从而免去打开、关闭相机的任务ListenableFuture<ProcessCameraProvider> cameraProviderListenableFuture = ProcessCameraProvider.getInstance(this);cameraProviderListenableFuture.addListener(() -> {try {cameraProvider = cameraProviderListenableFuture.get();// 预览preview = new Preview.Builder().build();preview.setSurfaceProvider(previewView.getSurfaceProvider());// 图片分析imageAnalysis = new ImageAnalysis.Builder()// 设置输出图片格式.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888)// 非阻塞模式,只取最新的图片。若需要每帧图片都处理,使用阻塞模式 ImageAnalysis.STRATEGY_BLOCK_PRODUCER.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST).setTargetResolution(SIZE).build();imageAnalysis.setAnalyzer(executor, (imageProxy) -> {// close后才认为处理完成当前帧,所以放到try-with-resources语句中try (imageProxy) {// 在此处处理图片,如对图片进行人脸、条码识别等Log.i(TAG, "接收到一帧图片" + SIMPLE_DATE_FORMAT.format(new Date()));} catch (Exception exception) {Log.w(TAG, exception.getMessage());}});// 拍照imageCapture = new ImageCapture.Builder().setFlashMode(ImageCapture.FLASH_MODE_AUTO).setTargetResolution(SIZE).build();// 录制Recorder recorder = new Recorder.Builder().setQualitySelector(QualitySelector.from(Quality.FHD)).build();videoCapture = VideoCapture.withOutput(recorder);cameraProvider.unbindAll();camera = cameraProvider.bindToLifecycle(this, CAMERAS.get(cameraIndex), preview,imageCapture, videoCapture);} catch (ExecutionException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}, executor);}private void initButton() {initFlashButton();initSwitchButton();initImageCaptureButton();initVideoCaptureButtons();}/*** 视频操作按钮*/private void initVideoCaptureButtons() {startShopVideoButton = findViewById(R.id.camerax_video_capture_button);pauseResumeVideoButton = findViewById(R.id.camerax_video_capture_pause_button);// 开始/停止录制视频startShopVideoButton.setOnClickListener(view -> {if (videoCapture == null || executor == null) {return;}if (isRecordingStart) {videoRecording.stop();videoRecording = null;isRecordingStart = false;startShopVideoButton.setText(START_RECORD);// 视频录制停止后不显示"暂停/恢复录制"按钮pauseResumeVideoButton.setVisibility(View.GONE);// 录制视频完成后显示切换摄像头按钮switchCameraButton.setVisibility(View.VISIBLE);return;}PermissionUtils.checkPermission(this, Manifest.permission.RECORD_AUDIO);videoRecording = videoCapture.getOutput().prepareRecording(this, getMediaStoreOutputOptions()).withAudioEnabled().start(executor, videoRecordEvent -> {});isRecordingStart = true;startShopVideoButton.setText(STOP_RECORD);pauseResumeVideoButton.setText(PAUSE_RECORD);// 视频录制开始后显示"暂停/恢复录制"按钮pauseResumeVideoButton.setVisibility(View.VISIBLE);// 录制视频期间不允许切换摄像头,切换摄像头会终止录制switchCameraButton.setVisibility(View.GONE);});// 暂停/恢复录制视频pauseResumeVideoButton.setOnClickListener(view -> {if (videoCapture == null || executor == null || videoRecording == null || !isRecordingStart) {return;}if (isRecordingPause) {isRecordingPause = false;videoRecording.resume();pauseResumeVideoButton.setText(PAUSE_RECORD);} else {videoRecording.pause();isRecordingPause = true;pauseResumeVideoButton.setText(RESUME_RECORD);}});}/*** 拍照按钮*/private void initImageCaptureButton() {findViewById(R.id.camerax_image_capture_button).setOnClickListener(view -> {if (imageCapture == null || executor == null) {return;}imageCapture.takePicture(getImageOutputFileOptions(), executor,new ImageCapture.OnImageSavedCallback() {@Overridepublic void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {Log.i(TAG, "save picture success");Toast.makeText(CameraxPreviewActivity.this, "success", Toast.LENGTH_SHORT).show();}@Overridepublic void onError(@NonNull ImageCaptureException exception) {Log.w(TAG, "error" + exception.getMessage());Toast.makeText(CameraxPreviewActivity.this, "fail", Toast.LENGTH_SHORT).show();}});});}/*** 切换摄像头按钮*/private void initSwitchButton() {switchCameraButton = findViewById(R.id.camerax_switch_camera);switchCameraButton.setOnClickListener((view -> {if (cameraProvider == null) {return;}if (++cameraIndex >= CAMERAS.size()) {cameraIndex = 0;}cameraProvider.unbindAll();cameraProvider.bindToLifecycle(this, CAMERAS.get(cameraIndex), preview, imageAnalysis,imageCapture, videoCapture);resetButtonStatus(cameraIndex);}));}/*** 闪光灯按钮*/private void initFlashButton() {flashButton = findViewById(R.id.camerax_flash);flashButton.setOnClickListener(view -> {if (camera == null) {return;}boolean isTorchOff = camera.getCameraInfo().getTorchState().getValue() == TorchState.OFF;camera.getCameraControl().enableTorch(isTorchOff);flashButton.setText(camera.getCameraInfo().getTorchState().getValue() == TorchState.ON ? "关灯" : "开灯");});}/*** 重设按钮状态*/private void resetButtonStatus(int cameraIndex) {flashButton.setText("开灯");flashButton.setVisibility(cameraIndex == 0 ? View.VISIBLE : View.GONE);startShopVideoButton.setText(START_RECORD);pauseResumeVideoButton.setText(PAUSE_RECORD);pauseResumeVideoButton.setVisibility(View.GONE);}private ImageCapture.OutputFileOptions getImageOutputFileOptions() {return new ImageCapture.OutputFileOptions.Builder(getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI,getContentValues("image/png")).build();}private MediaStoreOutputOptions getMediaStoreOutputOptions() {return new MediaStoreOutputOptions.Builder(getContentResolver(),MediaStore.Video.Media.EXTERNAL_CONTENT_URI).setContentValues(getContentValues("video/mp4")).build();}private ContentValues getContentValues(String mimeType) {String name = SIMPLE_DATE_FORMAT.format(new Date());ContentValues contentValues = new ContentValues();contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/HeTools");}return contentValues;}
}
参考文章
- 开始使用Android相机
相关文章:
安卓CameraX的使用
如果要在安卓应用中操作相机,有三个库可以选: Camera(已废弃):Camera是安卓最早的包,目前已废弃,在Android 5.0(API 级别 21)的设备上操作相机可以选择该包,…...
unity3d——基础篇小项目(开始界面)
示例代码: using System.Collections; using System.Collections.Generic; using UnityEngine;public class BeginPanel : BasePanel<BeginPanel> {public UIButton btnBegin;public UIButton btnRank;public UIButton btnSetting;public UIButton btnQuit; …...
【YOLOv8】安卓端部署-1-项目介绍
【YOLOv8】安卓端部署-1-项目介绍 1 什么是YOLOv81.1 YOLOv8 的主要特性1.2 YOLOv8分割模型1.2.1 YOLACT实例分割算法之计算掩码1.2.1.1 YOLACT 的掩码原型与最终的掩码的关系1.2.1.2 插值时的目标检测中提取的物体特征1.2.1.3 coefficients(系数)作用1.…...
安卓手机root+magisk安装证书+抓取https请求
先讲一下有这篇文章的背景吧,在使用安卓手机fiddler抓包时,即使信任了证书,并且手机也安装了证书,但是还是无法捕获https请求的问题,最开始不知道原因,后来慢慢了解到现在有的app为了防止抓包,把…...
11.20 深度学习-pytorch包和属性的基础语法
import torch import numpy as np def sci_close(): # 关闭pytorch 数据打印出来时科学计数法 torch.set_printoptions(sci_modeFalse) pass return 0 def create_tensor(): # 创建张量 t1torch.tensor(5) # 一阶张量 阶数看你传入的矩阵是多少阶的 这个是标量 不是一阶 一阶…...
SpringMVC域对象共享数据
目录 一.向 request 域对象共享数据 1.1使用ServletAPI向request域对象共享数据 1.2使用ModelAndView向request域对象共享数据 1.3使用Model向request域对象共享数据 1.4使用map向request域对象共享数据 1.5使用ModelMap向request域对象共享数据 二.Model、ModelMap、Ma…...
每日论文23-24ESSERC 6.4-16.1Ghz混合并联-串联谐振器
《A 6.4-to-16.1GHz Hybrid Parallel-Series Resonator Mode-Switching Oscillator with 206.6dBc/Hz FoMT at 1MHz Offset in 40nm CMOS》 24ESSERC 首先这篇文章有个地方我其实没太明白,它在title和行文的时候都写的是“ hybrid parallel-series resonator mode-…...
【软考】系统架构设计师-信息安全技术基础
信息安全核心知识点 信息安全5要素:机密性、完整性、可用性、可控性、审查性 信息安全范围:设备安全、数据安全、内容安全、行为安全 网络安全 网络安全的隐患体现在:物理安全性、软件安全漏洞、不兼容使用安全漏洞、选择合适的安全哲理 …...
kali搭建pikachu靶场
前言: 总所周知搭个网站需要有apachemysqlphp,Apache是一个开源的Web服务器软件, MySQL是一种关系型数据库管理系统(数据库),PHP是一种在服务器上执行的脚本语言 文章内容来自:【黑帽编程与攻…...
注解用于从 HTTP 请求中提取数据
在 Spring 框架中,PathVariable、RequestParam 和 RequestBody 等注解用于从 HTTP 请求中提取数据。具体来说: PathVariable:用于从 URL 路径中提取变量值。例如,在路径 /users/{id} 中,{id} 是一个路径变量。Request…...
(Linux)搭建静态网站——基于http/https协议的静态网站
简单了解nginx配置文件 1.下载并开启nginx服务 下载 [rootlocalhost ~]# dnf install nginx -y开启 [rootlocalhost ~]# systemctl restart nginx 1.(1)搭建静态网站——基于http协议的静态网站 实验1:搭建一个web服务器,访问该服务器时显示“hello w…...
【机器学习chp3】判别式分类器:线性判别函数、线性分类器、广义线性分类器、分段线性分类器
前言: 本文遗留问题:(1)对最小平方误差分类器的理解不清晰.(2)分段线性判别函数的局部训练法理解不清晰。 推荐文章1,其中有关于感知机的分析 【王木头从感知机到神经网络】-CSDN博客 推荐文…...
【学习】【HTML】HTML、XML、XHTML
HTML 什么是 HTML? HTML (HyperText Markup Language) 是一种用于创建和展示网页的标准标记语言。它由一系列的元素组成,这些元素通过标签的形式来告诉浏览器如何显示内容。 HTML 的基本结构是什么? <!DOCTYPE html> <html> …...
ARM中ZI-data段和RW-data段
ARM中ZI-data段和RW-data段 1、只定义全局变量,不使用,不占用内存空间2、 定义并初始化全局变量为0 占用ZI-Data区域3、定义并初始化全局变量非0 占用RW-Data区域4、增加的是一个int8的数据为什么,size增加不是15、定义的全局变量为0…...
关联度分析、灰色预测GM(1,1)、GM(1,1)残差模型——基于Python实现
关联度分析 import numpy as np import pandas as pd #关联度分析 #参考序列 Y_0[170,174,197,216.4,235.8] #被比较序列 Y_1[195.4,189.9,187.2,205,222.7] Y_2[308,310,295,346,367]#初始化序列 X_0np.array(Y_0)/Y_0[0] X_1np.array(Y_1)/Y_1[0] X_2np.array(Y_2)/Y_2[0]#计…...
linux常用命令(网络相关)
目录 1. ping - 检查网络连通性 参数 示例 2. ifconfig - 配置网络接口 参数 示例 3. ip - 显示和操作路由、网络设备、接口等 参数 示例 4. netstat - 显示网络连接、路由表、接口统计等信息 参数 示例 5. ss - 更快的netstat替代品 参数 示例 6. nslookup - …...
【uni-app多端】修复stmopjs下plus-websocket无心跳的问题
从这篇文章接着向下看: uniapp plus-websocket 和stompjs连接教程 安卓ios手机端有效 - 简书 按照文章的方式,能够实现APP下stmopjs长连接。但是有一个问题,就是会频繁输出 res-创建连接-1- 跟踪连接,会发现连接都会在大约40s后…...
VScode学习前端-01
小问题合集: vscode按!有时候没反应,有时候出来,是因为------>必须在英文状态下输入! 把鼠标放在函数、变量等上面,会自动弹出提示,但挡住视线,有点不习惯。 打开file->pre…...
Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片段
点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatisÿ…...
突破自动驾驶瓶颈!KoMA:多智能体与大模型的完美融合
0.简介 本推文主要介绍了由来自北京航空航天大学的姜克谋、蔡轩和崔智勇教授等共同提出的一种名为KoMA的知识驱动的多智能体框架。论文《KoMA: Knowledge-driven Multi-agent Framework for Autonomous Driving with Large Language Models》提出了KoMA框架,通过结…...
YOLO入门教程(三)——训练自己YOLO11实例分割模型并预测【含教程源码+一键分类数据集 + 故障排查】
目录 引言前期准备Step0 环境部署1.安装OpenCV2.安装Pytorch3.安装Ultralytics Step1 打标训练Step2 格式转换Step3 整理训练集Step4 训练数据集4.1创建yaml文件4.2训练4.3预测4.4故障排查4.4.1OpenCV版本故障,把OpenCV版本升级到4.0以上4.4.2NumPy版本故障…...
【加入默语老师的私域】C#面试题
什么是依赖注入,如何实现? 依赖注入是一种设计模式。我们不是直接在另一个类(依赖类)中创建一个类的对象,而是将对象作为参数传递给依赖类的构造函数。它有助于编写松散耦合的代码,并有助于使代码更加模块…...
称重传感器指示器行业全面且深入的分析
称重传感器指示器是一种用于显示和解释称重传感器输出信号的设备,用于测量力、重量或压力。称重传感器是将物理力(如重量)转换为电信号的传感器,称重传感器指示器将该电信号转换为可读格式,通常以磅、公斤或牛顿等单位…...
NAT网络地址转换——Easy IP
NAT网络地址转换 Tip: EasylP没有地址池的概念,使用接口地址作为NAT转换的公有地址。EasylP适用于不具备固定公网IP地址的场景:如通过DHCP, PPPOE拨号获取地址的私有网络出口,可以直接使用获取到的动态地址进行转换。 本次实验模拟nat协议配置 AR1配置如下&…...
【Visual Studio系列教程】如何在 VS 上编程?
上一篇博客中,我们介绍了《什么是 Visual Studio?》。本文,我们来看第2篇《如何在 VS 上编程?》。阅读本文大约10 分钟。我们会向文件中添加代码,了解 Visual Studio 编写、导航和了解代码的简便方法。 本文假定&…...
Mybatis-Plus 多租户插件属性自动赋值
文章目录 1、Mybatis-Plus 多租户插件1.1、属性介绍1.2、使用多租户插件mavenymlThreadLocalUtil实现 定义,注入租户处理器插件测试domianservice & ServiceImplmapper 测试mapper.xml 方式 1.3、不使用多租户插件 2、实体对象的属性自动赋值使用1. 定义实体类2. 实现 Meta…...
AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu
Ubuntu 上实现 AWTK-WIDGET-WEB-VIEW 开始以为很简单,后来发现是最麻烦的。因为 Ubuntu 上的 webview 库是 基于 GTK 的,而 AWTK 是基于 X11 的,两者的窗口系统不同,所以期间踩了几个大坑。 1. 编译 AWTK 在使用 Linux 的输入法时…...
Python入门(7)--高级函数特性详解
Python高级函数特性详解 🚀 目录 匿名函数(Lambda)装饰器的使用生成器与迭代器递归函数应用实战案例:文件批处理工具 1. 匿名函数(Lambda)深入解析 🎯 1.1 Lambda函数基础与进阶 1.1.1 基本…...
【数据库原理】理解数据库,基础知识
第一代:网状数据库;第二代:关系数据库;第三代:新一代数据库系统BigData 一、理解数据库 什么是数据:信息,对事物的存在方方式、运动状态及特征的描述。数据,记录信息的识别方式有数…...
VConsole——(H5调试工具)前端开发使用于手机端查看控制台和请求发送
因为开发钉钉H5微应用在手机上一直查看不到日志等,出现安卓和苹果上传图片一边是成功的,一边是失败的,所以找了这个,之前在开发微信小程序进行调试的时候能看到,之前没想到过,这次被人提点发现可以单独使用…...
wordpress购买会员资格/网站播放视频速度优化
PDF转CAD怎么弄?相信大家在做设计的时候肯定遇到过这种情况,就接到一个室内设计的项目,由于面积较大,或者形状不规则,现场量尺比较麻烦,善解人意的甲方提供了原建筑图纸,当你满心欢喜的收到图纸…...
用凡客建站做的网站有哪些/山东大学经济研究院
近两年像LOL、吃鸡这种竞技类游戏从来都是国内游戏市场中的常青树,尤其是英雄联盟,运营多年至今热度不减反增,保持这种状态实在难能可贵,其中很大的原因是这种MOBA类游戏往往靠技术说话,而至于氪金多少只能彰显在外观是…...
网站后台管理系统如何使用/seo属于运营还是技术
2019独角兽企业重金招聘Python工程师标准>>> 程序员在编程的时候难免会犯错误,但如果不从错误中吸取教训,那么习惯成自然,你会经常犯错的。从错误中不断的学习,锻炼好的行为习惯有助于事业上的稳定。这就是我们如何将小…...
网站设计和建设自考题/广州网络营销推广公司
最近了解了下缓存技术,主要分为内存缓存 和磁盘缓存,然后分布式里面有一些消息的推送,节点的一些处理。现在很多的用OSCache,EhCache 等等,资料很多,暂时就不多说了,我这里仅仅为了了解缓存框架的的知识&am…...
城乡建设学校官方网站/站外推广渠道
卓老师,我有一个信号与系统的问题想请教。按照时域采样定理,采样频率≥2倍的信号频率,才能得到信号全部信息。而以智能车中的编码器测速为例。我们知道测速周期在可接受范围内越小越利于控速,比如2ms。但2ms采样一次速度ÿ…...
张家口网站建设zjktao/百度一下移动版首页
什么是高压均质? 均质原理:样品(乳液或悬浮液)在高压下通过均质阀产生剪切、撞击、空穴作用。当样品在高压下通过均质阀,样品加速并在压力下势能转换,产生剪切效应、撞击效应和空穴效应。可应用于…...