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

Android 绘图基础:Canvas画布——自定义View基础(绘制表盘、矩形、圆形、弧、渐变)

  Canvas画布,通过它我们可以自定义一个View,设置View的相关效果之类的。感觉用法差不多,重要的是要理解方法中传入的参数的含义,比如float类型的参数,传递的是坐标,已开是没有注意传入的参数时坐标,导致我迷糊了一段时间,希望大家不要犯我的错误,记住是坐标啊!。

一、Canvas画布介绍

The Canvas class holds the “draw” calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).  

  关于Canvas网上也没有什么好的介绍, 我就直接从API中复制过来的,这里翻译一下。

  Canvas 支持“绘制”调用,想要进行绘制,你需要4个基本组成:一个由像素构成的位图,支持绘制调用的画布(绘制位图),一个图元(如矩形,路径,文本,位图),和油漆(用于绘制图的颜色和样式)。

(上面的四个基本组成会在后面代码部分进行解释)

  API中说的究竟是什么意思呢?我们可以把这个Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API。这样我们就可以在画布上进行绘制了。

二、使用步骤

  上面说了那么多是不是特别想知道它要怎样使用呢?现在我们就来说说他的使用步骤。

2.1使用步骤

1、写一个class类继承自View

2、在继承的class中写它的两个构造器,以前的版本中我们只需要写它的两个构造器(一个构造器参数为View(Context)另一个构造器参数为 View(Context AttributeSet) ),现在版本的升级又新出了两个构造器(View(Context attribute style)带有主题样式的),不管那么多,我们还是只写本来的两个构造器就OK了。

3、在该class中调用onDraw方法和onMeasure()方法。

4、在布局中使用该View

5、进行绘制

2.1使用示例

  下面我们按照上面的步骤一步步进行

1、写一个class类继承自View

public class MyView extends View

2、在继承的class中写它的两个构造器

public MyView(Context context) {

super(context);

}

public MyView(Context context, AttributeSet attrs) {

super(context, attrs);

}

  1. 在该class中重写onDraw方法和onMeasure()方法。

onDraw(我们将在该方法中进行绘制图形)

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

}

onMeasure(获得画布的高度与宽度)

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);

height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);

}

补充:由于onMeasure方法中本身就有获取高度与宽度的方法,我们直接点进去(ctrl+左键),复制出来就可以了。

  1. 在布局中使用该View(布局时必须写全包名+类名)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity" >

<com.example.myview.MyView

android:layout_width="match_parent"

android:layout_height="match_parent"

5、进行绘制

我们要如何进行绘制呢?首先我们看些Canvas都能绘制写什么。

drawRect(float left, float top, float right, float bottom, Paint paint)

//绘制矩形(左上右下的坐标,我们可以理解为左上的坐标为我们确定了矩形的左上角点,右下坐标为我们确定了右下角的点,这样一个矩形区域就确定出来了,paint为画笔)

drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)

//绘制圆角矩形(左上右下的坐标)

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

//绘制弧(参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始,

参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,实际绘制的是扇形,如果它是假这将是一个弧线,参数五是Paint对象)

drawOval(float left, float top, float right, float bottom, Paint paint)

//绘制椭圆

drawLine(float startX, float startY, float stopX, float stopY, Paint paint)

//绘制直线(XY起止坐标)

drawCircle(float cx, float cy, float radius, Paint paint)

//绘制圆形

drawText(String text, float x, float y, Paint paint)

//绘制文本

其他的不再进行列举,有需要可以查看API文档。

在参数中可以看到我们画图是需要画笔的,下面我们再来看下画笔(画漆)。这里展示一段代码相信你就能够明白了。

Paint mpaintline = new Paint();

mpaintline.setColor(Color.RED);

//设置线宽

mpaintline.setStrokeWidth(10);

//设置抗锯齿

mpaintline.setAntiAlias(true);

//设置空心,比如画实心圆还是空心圆

mpaintcircle.setStyle(Paint.Style.STROKE);

mpainttext.setTextSize(30);

//设置字的位置

mpainttext.setTextAlign(Align.CENTER);

mpainttext.setColor(Color.BLACK);

2.2表盘示例

上面说了那么多,我们来看一个具体而完整的实例,来整理一下思路。

public class MyView extends View

private int width;

private int height;

private Paint mpaintline;

private Paint mpaintcircle;

private Paint mpainttext;

private Calendar mcalendar;

private static final int NEED_INVALIDATE=0x23;

private Handler mhandler=new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case NEED_INVALIDATE:

//重新获取时间

mcalendar=Calendar.getInstance();

//重新绘制界面

invalidate();//告诉UI主线程重新绘制

//再次发送消息,递归调用,再次监测秒针

mhandler.sendEmptyMessageDelayed(NEED_INVALIDATE, 1000);

break;

default:

break;

}

};

};

public MyView(Context context) {

super(context);

}

public MyView(Context context, AttributeSet attrs) { //为了不是每次都创建Paint,我们在这里创建

super(context, attrs);

mcalendar=Calendar.getInstance();

mpaintline = new Paint();

mpaintline.setColor(Color.RED);

//设置线宽

mpaintline.setStrokeWidth(10);

//设置抗锯齿

mpaintline.setAntiAlias(true);

mpaintcircle = new Paint();

mpaintcircle.setColor(Color.GREEN);

mpaintcircle.setStrokeWidth(10);

//设置空心

mpaintcircle.setStyle(Paint.Style.STROKE);

mpainttext=new Paint();

mpainttext.setTextSize(30);

mpainttext.setTextAlign(Align.CENTER);

mpainttext.setColor(Color.BLACK);

//发送消息,监测秒针

mhandler.sendEmptyMessage(NEED_INVALIDATE);

}

//在此方法中进行绘制

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//绘制圆形

canvas.drawCircle(width/2, height/2, width/2-20, mpaintcircle);

//绘制表芯

canvas.drawCircle(width/2, height/2, 5, mpaintcircle);

//绘制表盘时我们采用旋转画布的思想,让画布进行旋转一定角度,绘制

for(int i=1;i<=12;i++){

//保存画布当前状态

canvas.save();

//指定旋转角度与旋转点

canvas.rotate(360/12*i,width/2,height/2);

//绘制表盘

canvas.drawLine(width/2, height/2-(width/2-20), width/2,height/2-width/2+40, mpaintline);

//绘制文字

canvas.drawText(""+i, width/2, height/2-width/2+70, mpainttext);

//恢复开始位置

canvas.restore();

}

int minute=mcalendar.get(Calendar.MINUTE);

int hour=mcalendar.get(Calendar.HOUR);

int second=mcalendar.get(Calendar.SECOND);

float minudegrees=minute/60f*360;

float hourdregrees=hour*60/12f/60*360;

float senconddegree=second/60f*360;

//绘制分针

canvas.save();

canvas.rotate(minudegrees,width/2,height/2);

canvas.drawLine(width/2, height/2, width/2, height/2-width/2+90, mpaintline);

canvas.restore();

//绘制时针

canvas.save();

canvas.rotate(hourdregrees,width/2,height/2);

canvas.drawLine(width/2, height/2, width/2, height/2-width/2+100, mpaintline);

canvas.restore();

//绘制秒针

canvas.save();

canvas.rotate(senconddegree,width/2,height/2);

canvas.drawLine(width/2, height/2, width/2, height/2-width/2+60, mpaintline);

canvas.restore();

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//固定

2.3绘制圆形progressbar

这里模拟下载,自定义了一个ProgressBar。在MyProgressCircle 中定义出最大进度和当前进度,给出当前进度的SET\GET方法,通过Mainactivity中改变Progres的当前进度,根据当前进度,不停修改半径,重新绘制表层绿色圆形。

public class MyProgressCircle extends View{

private int width;

private int height;

private int Maxprogress=100;

private int Currentprogress;

private Paint PaintBackGround;

private Paint PaintCurrent;

private Paint PaintText;

public int getMaxprogress() {

return Maxprogress;

}

public void setMaxprogress(int maxprogress) {

Maxprogress = maxprogress;

}

//当前进度的set、get方法

public int getCurrentprogress() {

return Currentprogress;

}

public void setCurrentprogress(int currentprogress) {

Currentprogress = currentprogress;

invalidate();

}

public MyProgressCircle(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

public MyProgressCircle(Context context, AttributeSet attrs) {

super(context, attrs);

PaintBackGround=new Paint();

PaintBackGround.setColor(Color.GRAY);

PaintBackGround.setAntiAlias(true);

PaintBackGround.setStrokeWidth(10);

PaintCurrent=new Paint();

PaintCurrent.setColor(Color.GREEN);

PaintCurrent.setAntiAlias(true);

PaintCurrent.setStrokeWidth(10);

PaintText=new Paint();

PaintText.setColor(Color.BLACK);

PaintText.setAntiAlias(true);

PaintText.setTextAlign(Align.CENTER);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawCircle(width/2, height/2,width/2-30 , PaintBackGround);

//根据当前进度改变半径,绘制圆形

canvas.drawCircle(width/2, height/2,(float) (width/2-30)*Currentprogress/Maxprogress, PaintCurrent);

canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);

height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);

}

}

MainActivity中改变progress进度

public class MainActivity extends Activity implements OnClickListener{

private Button btn_circle_progress;

private MyProgressCircle myprogresscircle;

private int progress;

private Handler mhanHandler=new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case 0x23:

progress++;

if(progress<=100){

myprogresscircle.setCurrentprogress(progress);

mhanHandler.sendEmptyMessageDelayed(0x23, 200);

}

break;

default:

break;

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.circle_progress);

btn_circle_progress=(Button) findViewById(R.id.mbtn_circleprogress);

myprogresscircle=(MyProgressCircle) findViewById(R.id.mycircleprogress);

btn_circle_progress.setOnClickListener(this);

}

@Override

public void onClick(View v) {

mhanHandler.sendEmptyMessageDelayed(0x23, 1000);

}

}

2.4绘制弧形progressbar

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//设置画弧的区域

RectF oval1=new RectF(width/2-100,height/2-100,width/2+100,height/2+100);

canvas.drawArc(oval1, 270, Currentprogress, false, PaintCurrent);//第二个参数:顺时针起始位置;第三个参数:顺时针转的弧

canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);

}

MainActivity

public class MainActivity_ARC extends Activity implements OnClickListener{

private Button btn_arc_progress;

private MyArcProgress myprogressarc;

private int progress;

private Handler mhanHandler=new Handler(){

public void handleMessage(android.os.Message msg) {

switch (msg.what) {

case 0x23:

progress++;

if(progress<=360){

myprogressarc.setCurrentprogress(progress);

mhanHandler.sendEmptyMessageDelayed(0x23, 200);

}

break;

default:

break;

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.arc_progress);

btn_arc_progress=(Button) findViewById(R.id.mbtn_arcprogress);

myprogressarc= (MyArcProgress) findViewById(R.id.myarcprogress);

btn_arc_progress.setOnClickListener(this);

}

@Override

public void onClick(View v) {

mhanHandler.sendEmptyMessageDelayed(0x23, 1000);

}

}

2.5绘制多条线与矩形

public class MyRectProgress extends View{

private int width;

private int height;

private int Maxprogress=100;

private int Currentprogress;

private Paint PaintBackGround;

private Paint PaintCurrent;

private Paint PaintText;

private int i;

private float[] lines=new float[400];

public int getMaxprogress() {

return Maxprogress;

}

public void setMaxprogress(int maxprogress) {

Maxprogress = maxprogress;

}

public int getCurrentprogress() {

return Currentprogress;

}

public void setCurrentprogress(int currentprogress) {

Currentprogress = currentprogress;

lines[i]=50;

i++;

lines[i]=50+250f*Currentprogress/Maxprogress;

i++;

lines[i]=300;

i++;

lines[i]=50+250f*Currentprogress/Maxprogress;

invalidate();

}

public MyRectProgress(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

public MyRectProgress(Context context, AttributeSet attrs) {

super(context, attrs);

PaintBackGround=new Paint();

PaintBackGround.setColor(Color.GRAY);

PaintBackGround.setAntiAlias(true);

PaintBackGround.setStrokeWidth(10);

PaintCurrent=new Paint();

PaintCurrent.setColor(Color.GREEN);

PaintCurrent.setAntiAlias(true);

PaintCurrent.setStrokeWidth(5);

PaintText=new Paint();

PaintText.setColor(Color.BLACK);

PaintText.setAntiAlias(true);

PaintText.setTextAlign(Align.CENTER);

PaintText.setTextSize(30);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//canvas.drawCircle(width/2, height/2,width/2-30 , PaintBackGround);

canvas.drawRect(50,50 ,300, 300, PaintBackGround);

canvas.drawLines(lines, PaintCurrent);

//canvas.drawLine(50,50+250f*Currentprogress/Maxprogress, 300, 50+250f*Currentprogress/Maxprogress, PaintCurrent);

canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);

height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);

}

}

2.5绘制渐变

样式就是我们开始时图片展示的样式

package com.example.myview;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.LinearGradient;

import android.graphics.Paint;

import android.graphics.Paint.Align;

import android.graphics.RectF;

import android.graphics.Shader;

import android.util.AttributeSet;

import android.view.View;

public class MyotherProgress extends View{

private int width;

private int height;

private int Maxprogress=100;

private int Currentprogress;

private Paint PaintBackGround;

private Paint PaintCurrent;

private Paint PaintText;

public int getMaxprogress() {

return Maxprogress;

}

public void setMaxprogress(int maxprogress) {

Maxprogress = maxprogress;

}

public int getCurrentprogress() {

return Currentprogress;

}

public void setCurrentprogress(int currentprogress) {

Currentprogress = currentprogress;

invalidate();

}

public MyotherProgress(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

public MyotherProgress(Context context, AttributeSet attrs) {

super(context, attrs);

PaintBackGround=new Paint();

PaintBackGround.setColor(Color.GRAY);

PaintBackGround.setAntiAlias(true);

PaintBackGround.setStrokeWidth(10);

PaintCurrent=new Paint();

PaintCurrent.setColor(Color.GREEN);

PaintCurrent.setAntiAlias(true);

PaintCurrent.setStrokeWidth(10);

/* 设置渐变色 颜色是改变的 */

Shader mShader = new LinearGradient(0, 0, 100, 100,

new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,

Color.LTGRAY }, null, Shader.TileMode.REPEAT);

PaintCurrent.setShader(mShader);

PaintText=new Paint();

PaintText.setColor(Color.BLACK);

PaintText.setAntiAlias(true);

PaintText.setTextAlign(Align.CENTER);

PaintText.setTextSize(30);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

//底层圆形

canvas.drawCircle(width/2, height/2,width/2-30 , PaintBackGround);

// 设置个新的长方形,扫描测量

RectF oval = new RectF(30,height/2-(width/2-30 ) , width-30 , height/2+width/2-30 );

//绘制扇形

// 画弧,第一个参数是RectF(确定绘制区域):

//该类是第二个参数是角度的开始,

//第三个参数是多少度,

//第四个参数是真的时候画扇形,是假的时候画弧线

canvas.drawArc(oval, 0, Currentprogress*360f/100, true, PaintCurrent);

canvas.drawText(Currentprogress*100f/Maxprogress+"%", width/2,height/2, PaintText);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);

height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);

}

}

相关文章:

Android 绘图基础:Canvas画布——自定义View基础(绘制表盘、矩形、圆形、弧、渐变)

Canvas画布&#xff0c;通过它我们可以自定义一个View&#xff0c;设置View的相关效果之类的。感觉用法差不多&#xff0c;重要的是要理解方法中传入的参数的含义&#xff0c;比如float类型的参数&#xff0c;传递的是坐标,已开是没有注意传入的参数时坐标&#xff0c;导致我迷…...

js拷贝数组对象:浅拷贝深拷贝

前言 js拷贝数组对象&#xff1a;浅拷贝&深拷贝&#xff0c;包括&#xff1a;Object.assign、concat、slice、JSON.parse(JSON.stringify()) 场景&#xff1a;弹窗选择组织结构&#xff08;树形结构&#xff09;&#xff0c;选择后显示相关数据至输入框中&#xff08;每次选…...

【C++】string类的使用

目录 一、标准库中的string类 二、string类的常用接口 1、string类对象的常见构造 2、string类对象的容量操作 2.1、size 与 length 2.2、capacity 与 reserve 2.3、resize 2.4、总结 3、string类对象的访问及遍历操作 3.1、operator[] 与 at 3.2、begin end 3.3、…...

微服务架构简介

微服务 软件架构是一个包含各种组织的系统组织&#xff0c;这些组件包括 Web服务器, 应用服务器, 数据库,存储, 通讯层), 它们彼此或和环境存在关系。系统架构的目标是解决利益相关者的关注点。 image Conway’s law: Organizations which design systems[...] are constrained…...

【Spring源码】AOP的开端:核心对象创建的准备工作

AOP的核心成员是如何被被加载的&#xff1f;本篇我们主要分析使用xml的逻辑&#xff0c;如果使用注解&#xff0c;增加注解处理类即可&#xff08;ConfigurationClassPostProcessor&#xff09;拿之前分析循环的时候举的例子&#x1f330;&#xff0c;它的日志切面就是通过xml进…...

新号涨粉22w,搞笑博主再次爆火,小红书近期创作趋势是什么?

2月借势元宵、情人节&#xff0c;小红书平台又涌现出哪些黑马博主&#xff1f;品牌在投放种草方面有何亮眼表现&#xff1f;为洞察小红书平台的内容创作趋势及品牌营销策略&#xff0c;新红推出2月月度榜单&#xff0c;从创作者及品牌两方面入手&#xff0c;解析月榜数据&#…...

【C++】30h速成C++从入门到精通(内存管理、函数/类模板)

C内存分布我们先来看一下下面的一段代码相关问题int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pChar3 "abcd";int* ptr1 (int*)mal…...

自动驾驶决策概况

文章目录1. 第一章行为决策在自动驾驶系统架构中的位置2. 行为决策算法的种类2.1 基于规则的决策算法2.1.1 决策树2.1.2 有限状态机&#xff08;FSM&#xff09;2.1.3 基于本体论&#xff08;Ontologies-based&#xff09;2.2 基于统计的决策算法2.2.1 贝叶斯网络&#xff08;B…...

金山轻维表项目进展自动通知

项目经理作为项目全局把控者&#xff0c;经常要和时间“赛跑”。需要实时了解到目前进展如何&#xff0c;跟进人是那些&#xff1f;哪些事项还未完成&#xff1f;项目整体会不会逾期&#xff1f;特别是在一些大型公司中&#xff0c;优秀的项目经理已经学会使用金山轻维表做项目…...

基于上下文分析的 Python 实时 API 推荐

原文来自微信公众号“编程语言Lab”&#xff1a;基于上下文分析的 Python 实时 API 推荐 搜索关注 “编程语言Lab”公众号&#xff08;HW-PLLab&#xff09;获取更多技术内容&#xff01; 欢迎加入 编程语言社区 SIG-程序分析 参与交流讨论&#xff08;加入方式&#xff1a;添加…...

软件测试-接口测试-代码实现接口测试

文章目录 1.request1.1 request介绍1.2 发送get请求1.3 发送set请求1.4 其他请求方式1.5 传递url参数1.6 响应内容解析1.7 cookie1.8 设置session2.集成UnitTest2.1 接口测试框架开发2.2 案例:使用TPShop项目完成对登录功能的接口测试1.request 1.1 request介绍 概念 基于py…...

中村成洋《垃圾回收的算法与实现》PDF 读书笔记

观前提醒 为了能够锻炼自己&#xff0c;我会查阅大量外文不停的修改内容&#xff0c;少部分会提示成中文。 可能有误&#xff0c;请见谅 提示&#xff1a;若是觉得阅读困难&#xff0c;可以看如下内容 脚本之家可获取&#xff0c;若失效可私信浏览器的沙拉查词扩展&#xf…...

docker 网络模式

docker 网络模式主要分为四种&#xff0c;可以通过docker network ls 查看 ~$ docker network ls NETWORK ID NAME DRIVER SCOPE a51d97d72f10 bridge br…...

数据库开发(一文概括mysql基本知识)

Mysql 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 关系型数据库(Relational Database Management System&#xff1a;关系数据库管理系统)应用软件之一。mysql在问开发中&#xff0c;几乎必不可少&#xff0c;因为其他的可能是要收费的&#x…...

【JVM】详解Java内存区域和分配

这里写目录标题一、前言二、运行时数据分区2.1程序计数器(PC)2.2 Java虚拟机栈2.3 本地方法栈2.4 Java堆2.5 方法区2.5.1 运行时常量池2.6 直接内存三、HotSpot虚拟机对象探秘3.1 对象的创建3.2 对象的内存布局3.3 对象的访问定位一、前言 C/C需要自行回收和释放已经没用的对象…...

JAVA开发(史上最完整追本溯源JAVA历史、发展和学习)

(第二次世界大战1931-1945) 世界上最先进的技术往往是由于战争催生&#xff0c;在第二次世界大战中除了飞机&#xff0c;坦克和大炮的武器较量外&#xff0c;在隐秘战线的情报工作其实更为重要&#xff0c;在军队将领来往的电报中&#xff0c;为了防止军事情报的泄漏&#xff…...

Qt 防止程序退出

文章目录摘要QWidgetQML方法 1方法 2关键字&#xff1a; Qt、 eventFilter、 Close、 键盘、 任务管理器摘要 今天要聊得内容还是怎么防止别人关闭我的程序&#xff0c;之前都是在win下面&#xff0c;一般都是用过钩子连捕获键盘事件&#xff0c;完了吧对应的事件忽略&#x…...

【校验码 - 循环冗余校验码CRC】

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 目录 循环冗余校验码 1.多项式 2.CRC编码的组成 3.校验码的生成 4.例题&#xff1a; 循环冗余校验码 广泛地在网络通信及磁盘存储时采用。 1.多项式 在循环冗余校验(CRC)码中&#xff0c;无一例…...

【Rust】一文讲透Rust中的PartialEq和Eq

前言 本文将围绕对象&#xff1a;PartialEq和Eq&#xff0c;以及PartialOrd和Ord&#xff0c;即四个Rust中重点的Compare Trait进行讨论并解释其中的细节&#xff0c;内容涵盖理论以及代码实现。 在正式介绍PartialEq和Eq、以及PartialOrd和Ord之前&#xff0c;本文会首先介绍…...

Vulnhub靶场----9、DC-9

文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-9下载地址&#xff1a;https://download.vulnhub.com/dc/DC-9.zip kali&#xff1a;192.168.144.148 DC-9&#xff1a;192.168.144.158 二、渗透流程 1、信息收集nmap -T5 -A -p- -sV -sT 192.168.144.158思路&am…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...