自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(43)
  • 资源 (1)
  • 收藏
  • 关注

原创 记录一个温度曲线的View

最近做项目需求的看到需要自定义一个温度曲线的图。由于之前的同事理解需求的时候没有很好的理解产品的需求,将温度的折线图分成了两个View,温度高的在一个

2022-07-13 20:04:49 252 1

原创 一位苦逼程序员的找工作经历

  最近一个多月因为找工作的原因,一个多月没有更新技术博客了。这一篇博客也不是讲技术文章,而是我找工作的一个多月的一些想法还有一些关于Android开发的思考。  首先说一下我的个人的背景,我是本科2020年7月毕业的,截止目前为止工作了两年。我是在2017年的时候,也就是我大二的时候接触了java语言,大概是2018年的时候接触了android,然后并开始自己学习并且入门的android。在2018年的时候,由于个人思考的东西比较幼稚,而且那时候确实android看起来形式也很好,加上自己也比较喜欢做ap

2022-06-25 19:03:40 2495 6

原创 Android消息机制分析

Android消息机制分析Android的消息机制主要是指Handler的运行机制以及Handler所附带的MessageQueue和Looper的工作过程。这三者实际上是一个整体,只不过 我们在开发过程中比较多地接触到Handler而已。Handler的主要作用是将一个任务切换到某个指定的线程中去执行,那么Android为什么要提供这个功能呢? 或者说Android为什么需要提供在某个具体的线程中执行任务这种功能呢?这是因为Android规定访问UI只能在主线程中进行,如果在子线程中访问UI,那么程序就

2022-04-25 18:01:16 556 1

原创 MeasureSpec源码解读

今天来讲讲MeasureSpec吧。因为他与View的测量流程相关性很大,只有正确的理解了MeasureSpec的工作原理,我们才能更好的自定义View。那么MeasureSpec它的作用是什么呢?一般来说,它在很大程度上决定了一个View的尺寸规格。为什么是很大程度上呢?因为一个View的尺寸大小还可能和布局树中的父布局相关。想一想,如果你在你的子View中的布局参数写了match_parent,那么这个控件的大小是不是就和父布局相关了?所以说,我们今天的内容主要有以下两个方面,一个是MeasureSpe

2022-04-22 14:53:39 1879 1

原创 深入解析View的绘制源码流程

View的绘制流程今天来讲讲View的绘制流程吧,这一块也是我比较薄弱的地方,而且之前没有什么耐心去看这一块。今天就来学习这一块的知识点。主要分为3部分:View树的创建ViewRootImpl的创建真正的绘制流程开始performTraversalsView树的创建首先思考一个问题View的绘制从那里开始?关于这个问题我一开始也谷歌百度了很多东西,但是还是不能解决我的疑惑。所以今天我打算从根本上解决这个问题——从Activity的setContentView开始看。下面开始我的

2022-04-21 16:17:24 733

原创 Viewmodel源码解析

Viewmodel源码解析现在Viewmodel相信大家都比较熟悉了,adnroid的官网上也介绍了它的一些特性。具体的这里就不多讲了。今天就来讲解它的源码,讲解为什么它能够在配置发生变化的时候还能保存数据。现在在Activity和Fragment中怎么去初始化一个viewmodel呢?一般来讲就是通过谷歌给我们提供的扩展函数去初始化,具体如下val plantingsViewModel:PlantListViewModel by viewModels()所以今天,我就从这一个函数开始入手去看看V

2022-04-20 18:25:06 494

原创 浅析音视频同步原理

音视频同步今天我们来讲解一下音视频同步吧。讲完这篇,结合之前几篇博客,我们对音视频开发也算有一个入门级别的理解了。首先思考几个问题:1、为什么需要音视频同步?因为视频和音频是两个独立的任务在运行,视频和音频的解码速度也不一样,解码出来的数据也不一定马上就可以显示出来。视频:帧率,表示视频一秒显示的帧数。音频:采样率,表示音频一秒播放的样本的个数。从帧率及采样率,即可知道视频/音频播放速度。声卡和显卡均是以一帧数据来作为播放单位,如果单纯依赖帧率及采样率来进行播放,在理想条件下,应该是同步的

2022-04-15 15:10:43 249

原创 MediaCodec解析MP4视频

MediaCodec讲解MediaCodec是Android提供的用于对音视频进行编解码的类,它通过访问底层的codec来实现编解码的功能。是Android media基础框架的一部分,通常和 MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface和AudioTrack一起使用。MediaCodec支持的数据类型编解码器支持的数据类型:压缩的音视频数据,原始音频数据和原始视频数据。数据通过ByteB

2022-04-12 18:11:44 5254

转载 SurfaceView与TextureView的区别

SurfaceView与TextureViewSurfaceView在说SurfaceView之前,需要先说一下几个相关的部分。Surface简介Surface就是“表面”的意思,可以简单理解为内存中的一段绘图缓冲区。在SDK的文档中,对Surface的描述是这样的:“Handle onto a raw buffer that is being managed by the screen compositor”, 翻译成中文就是“由屏幕显示内容合成器(screen compositor)所管理的原

2022-04-11 11:19:40 4540

原创 Android屏幕刷新机制

Android屏幕刷新机制一些前置概念屏幕刷新率一秒内屏幕刷新的次数(一秒内显示了多少帧的图像),单位 Hz(赫兹),如常见的 60 Hz,90Hz,120Hz(高刷新率)。刷新频率取决于硬件的固定参数(不会变的)。逐行扫描显示器并不是一次性将画面显示到屏幕上,而是从左到右边,从上到下逐行扫描,顺序显示整屏的一个个像素点,不过这一过程快到人眼无法察觉到变化。以 60 Hz 刷新率的屏幕为例,这一过程即 1000 / 60 ≈ 16ms。帧率 (Frame Rate)表示 GPU 在

2022-04-07 13:11:26 1312

原创 MediaPlayer状态图及生命周期

MediaPlayer状态图及生命周期MediaPlayer是Android中的uoge多媒体播放类,我们能通过它控制音视频流或本地音视频资源的播放过程。这一片博客主要介绍MediaPlayer状态图及生命周期。先看一张官网很经典的MediaPlayer状态机的图片。其中椭圆代表MediaPlayer驻留状态,弧代表播放器控制且驱动MediaPlayer状态进行过度。有两种类型的弧,单箭头弧表示的是同步函数的调用,双箭头弧表示的是异步函数的调用。从上图中我们能够得知MediaPlayer有一下状态

2022-04-06 11:40:29 5434

原创 视频编码之I,P,B帧

视频编码之I,P,B帧编码主要是想办法压缩视频的大小。使用帧间编码技术可以去除时间上的冗余信息,具体包括以下几个部分。运动补偿:运动补偿是通过先前的局部图像来预测、补偿当前的局部图像,它是减少帧序列冗余信息的有效方法。运动表示:不同区域的图像需要使用不同的运动矢量来描述运动信息。运动估计:运动估计是从视频序列中抽取运动信息的一整套技术。使用帧内编码技术可以去除空间上的冗余信息。对于视频,ISO同样也制定了标准:Motion JPEG即MPEG,MPEG算法是适用于动态视频的压缩

2022-04-02 17:34:21 2505

转载 音视频开发入门

音视频开发入门视频播放器的原理我们首先来看一下视频播放器的原理,然后讲解一下里面的一些基本的概念。如图就是视频播放器的原理了。视频文件格式就是我们通常说的mp4,mkv,flv等等这些。这些文件格式也叫封装格式,那什么是封装格式呢?就是把视频数据和音频数据打包成一个文件的规范。视频里面是包括音频还有视频数据,所以也可以把它看作一个容器。注意,容器里面的数据是经过压缩后的数据。封装格式的主要作用是把视频码流和音频码流按照一定的格式存储在一个文件中。现如今流行的封装格式如下表所示:视频封装格

2022-04-02 11:47:41 2330

原创 BlockCanary源码解析

BlockCanary源码解析在讲解BlockCanary源码之前,我们还是需要将一些前置的知识点。本文不讲Handler的原理了,不太懂的同学自己去百度看一下吧。什么是卡顿在讲解卡顿问题之前,我们需要讲一下帧率这个概念。帧率是以帧称为单位的位图图像连续出现在显示器上的频率。我将一个例子,电影播放。电影其实就是很多张照片(帧)的一个集合,那为什么看起来是一个连续的过程呢?因为电影每一秒出现过的图片不止一张。实际上电影一般一秒出现的图片张数会在20-30张。假设电影一秒出现了24张图片,那么这个电影的帧

2022-03-24 17:43:41 2313

原创 LeakCanary源码分析

LeakCanary源码解析内存泄露今天来讲解一下老生常谈的问题了,内存泄露以及讲解LeakCanary是如果检测内存泄露的。大家都在讲内存泄露,那么内存泄露的最根本的原因是什么?**最根本的原因就是该回收的对象没有被即使回收掉,导致了内存泄露。**要理解这句话,就要对java的垃圾回收机制有一定的了解了。什么是垃圾回收呢?就是java虚拟机在运行的时候会触发垃圾回收的机制,将那些没有用的,占用内存的对象回收掉。java虚拟机是怎么判断这个对象有没有用呢?是根据GC ROOT的可达性算法去判断的。就是

2022-03-23 18:17:43 2744

原创 Glide的缓存源码分析

Glide的缓存流程上一篇讲解了Glide的整体流程,其实很多时候,只有第一次加载图片的时候,我们才会按照那一个流程去走。因为很多时候,我们都是有缓存了。有了缓存之后,加载流程就会稍微变一下了。那么今天,我们就来讲解一下Glide中的缓存。在讲解Glide缓存之后,我建议大家先去了解一下LinkedHashMap的实现。因为这里涉及到LRU算法。推荐大家一篇关于LinkedHashMap的博客:田小波关于LinkedHashMap的源码分析先来一张Glide缓存的流程图吧,让大家对Glide的流程有一个

2022-03-22 14:21:31 2313

原创 Glide源码分析之Glide的整体加载流程

  大家应该都听说过Glide图片加载库,或多或少都知道怎么去使用Glide去加载一张图片。Glide对于使用者来说是非常友好的一个库。那么今天我们就来学习Glide的源码,网上也有很有优秀的博客讲解Glide的源码的,现在我们一起来学习Glide的源码。这个优秀的框架是怎么帮助我们实现图片的加载和显示的。很多人看源码都不知道从哪里下手。这篇博客也分享一下我平时是怎么看源码的。这是基于Glide:4.10版本的源码分析  首先我们平时是怎么使用Glide的?Glide.with(context).loa

2022-03-15 17:33:13 890

原创 浅谈类的加载机制

类的加载机制我们知道,编译的过程是将java文件转换成class文件,也就是说我们在使用的时候,还是需要将class文件加载到我们的内存中我们才能使用的,这个过程就是类的加载机制,很多人会把这个知识点忽略掉,但是这个是非常重要的知识点,有助于我们去更深层次的学习java虚拟机的一些知识。今天我们就来学习一下类的加载机制。类的加载机制的定义:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是java虚拟机的加载机制。类

2022-02-16 10:20:15 675

原创 java中的垃圾回收算法

java中的垃圾回收算法​ 今天来讲讲java中的垃圾回收机制,要了解垃圾回收机制,我们就要先了解java堆,它的实现是什么。java堆的实现:​ 在java中堆的实现像一个传送带,每分配一个新的对象,它就向前移动一格。这就意味着对象存储空间的分配非常的快,java的“堆指针”只是简单的移动到尚未分配的区域。​ 但是java堆未必完全像上面将的那样工作,因为如果真的是那样的话,一定会导致频繁的内存页面调度——将其移进移出硬盘,页面调度会影响性能,最终在创建足够多的对象之后,内存耗尽。因为java中有

2022-02-14 16:10:47 5262

原创 面试必备之TCP协议详解

面试必备之TCP协议TCP协议无论是前端还是后端面试,都会被经常问到,而且在我们日常的开发中,这里面的一些知识对我们了解网络也有重要的意义。所以非常有必要去详细了解一下TCP协议。什么是TCP​ TCP是主要的网络协议之一,属于传输层的协议。它使两台主机能够建立连接并交换数据流。TCP 能保证数据的交付,维持数据包的发送顺序。TCP的特点:TCP是面向连接的传输层的协议。就是使用TCP协议之前,必须建立连接。在数据传输完成之后,必须释放已经建立的TCP连接。每一条TCP连接只能有两个端点

2022-02-10 09:48:32 2149

原创 从源码角度去理解Context

Android中的各种ContextContext家族之间的关系看以上这幅图,我们知道各个Context之间的关系。  首先Context是一个抽象类,它的实现由两个一个是ContextImpl,它是真是实现了Context里面的各种方法。ContextWrapper里面持有一个ContextImpl变量——mBase,调用ContextWrapper的实现方法,最终都是通过mBase去调用ContextImpl的实现方法。这里用的设计模式是装饰模式,ContextWrapper是装饰类。Conte

2022-01-19 14:30:30 386

原创 Android面试之Activity的启动流程详解

根Activity的启动过程根Activity的启动整体过程如下:主要分为四部分Launcher请求ATMS创建根ActivityATMS会去请求zygote创建应用程序进程zygote去创建应用程序进程ATMS请求ApplicationThread创建根Activity我们分析的话,不会按照上面的每一个步骤去分析。我们会按照下面三个部分去进行源码(android 10)的分析Launcher请求ATMS的过程ATMS到ApplicationThread的调用过程Activity

2022-01-13 18:51:57 2334

原创 Lifecycle与LiveData的珠联璧合

Lifecycle与LiveData的讲解lifecycleLifecycle是生命周期感知型组件,什么是生命感知型组件?就是与Activity或者Fragment绑定之后,可执行一些操作来响应Activity和Fragment的生命周期状态的变化。lifecycle是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并且允许其他对象观察此状态。Lifecycle使用两种主要枚举跟踪其关联组件的生命周期状态:这两个枚举类分别是State和Event。Stat

2022-01-07 17:24:57 1607

原创 Kotlin协程,我学“废”了

Kotlin协程  Kotlin协程(本文讲解的协程都是基于Kotlin讲解的,其他语言的协程不在本文章的讨论范围)目前很流行的一款用于异步任务处理的库,都知道它处理异步任务特别好用,但是很少人去探究它背后的原理。还有一点,由于它是用于处理异步任务的,很多人将协程与线程做对比,也有一些人将协程与Rxjava做对比。这篇文章将从最简单的用法开始,层层递进的讲解以下知识点:如何使用使用协程,以及协程中的一些重要概念协程怎么处理异步任务和并发任务挂起函数是什么协程底层是怎么实现挂起-恢复的协程是怎么

2022-01-04 11:56:35 1712

原创 JetPack之Hilt的使用

JetPack之Hilt的使用什么是依赖注入    讲解Hilt之前,我们先来理解什么是依赖注入以及依赖注入有什么用。    首先我们来看我们平时自己写代码 class LearnHilt { var firstMember:FirstMember = ... var secondMember:SecondMember = ... }    首先,这一个类有两个成员变量,firstMember和secondMember。这两个变量也叫做这个类的依赖。那么要初始化这两个依赖。

2021-12-20 23:12:30 641

原创 Jetpack之Room的使用

Room的使用Room 在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制。如何配置...apply plugin: 'kotlin-kapt' ...​dependencies {   ...    kapt "androidx.room:room-compiler:$rootProject.roomVersion"    implementation "androidx.

2021-12-16 11:45:00 2526

原创 java运行时数据区域

java运行时数据区域java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 这些区域每一个都有自己的用途。java虚拟机所管理的内存包括以下几个运行时数据区域。程序计数器程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型例,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要以来这个计数器完成。由于java虚拟机的多线程是通过线程轮流切换并分配

2021-11-18 09:43:21 627

原创 视图绑定(ViewBinding )与数据绑定(Databinding)

视图绑定(ViewBinding )与数据绑定(Databinding)什么是ViewBindingviewbinding是android jetpack的一个特性,通过viewbinding功能,您可以更轻松地编写可与视图交互的代码。在模块中启用viewbinding之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。用法如何配置Viewbinding在每一个模块中的build.gradle中进行如下配置 android

2021-09-28 00:30:33 3939 3

原创 kotlin中构造函数,伴生对象的讲解

kotlin中构造函数,伴生对象的讲解在kotlin中有一些知识点看起来好像挺简单的,好像我们使用着确实也没有问题?但是这不意味我们懂了这些只是点,我们只是知道了怎么用,要说懂,就需要我们去了解它们的本质。今天我们就介绍kotlin中,一些我们看似懂了,却又没有完全懂的知识点。Kotlin Class中那些被我们忽略的知识点首先第一个知识点是class,首先来看一个java类。 class MyJavaClass { static String staticMember; //静态变量

2021-09-26 22:15:34 508

原创 kotlin中的高阶函数、匿名函数与lambda 表达式

高阶函数、匿名函数与lambda 表达式Kotlin 函数都是头等的,这意味着它们可以存储在变量与数据结构中、作为参数传递给其他高阶函数以及从其他高阶函数返回。可以像操作任何其他非函数值一样操作函数。头等函数:头等函数(first-class function)是指在程序设计语言中,函数被当作头等公民。这意味着,函数可以作为别的函数的参数、函数的返回值,赋值给变量或存储在数据结构中。高阶函数高阶函数是将函数用作参数或返回值的函数。 //learnHighFun是一个高阶函数,因为他有一个函数类型的

2021-09-21 16:10:32 239

原创 Kotlin中的那些事之——作用域函数。run,with,let,also,apply

theme: github前言熟悉kotlin的同学都知道,kotlin中有一些很好用的函数。比如run,with,let,also,apply。我们平时写代码的过程中肯定都有在使用这些函数,但是我们使用的过程中有留意这些函数是怎么实现的吗?或者说我们有平时有去了解过这些函数的区别吗?如果没有了解过,那么不要紧,这篇文章带你去了解一下kotlin中的这几个基本的函数。在讲解这几个函数之前,我们首先去了解一个概念——作用域函数作用域函数在Kotlin有这么一类函数,它们的唯一目的是在对象的上下文中执.

2021-09-16 23:55:03 168

原创 主键和外键

主键(primary key):一列(或一组列),其值能够唯一区分表中每一行。唯一标识表中的每一行的这个列(或这组列)称为主键。主键用来表示一个特定的行,没有主键,更新或者删除表中的特定行很困难。应该总是定义的主键——虽然并不是总是都需要主键,但是大多数数据设计库人员都应该保证他们创建的每一个表中都有一个主键,以便于后面数据的管理个操作。表中任何列都可以作为主键,只要满足一下条件:任意两...

2019-12-06 22:59:44 3070

原创 mysql一些知识总结

mysql知识总结。如果存在就不插入的情况可以通过sql语句来操作。可以通过一条sql语句执行完,不必要通过查询出结果,然后在判断插不插入。例子:insert into tablename(columns1,columns2,...,columnsn) SELECT 'value1','value2',...,'valuen' FROM tablename WHERE NOT EXI...

2019-12-05 17:49:54 80

原创 事务的基本知识点

事务: 它是一些列严密操作动作,要么都操作完成,要么都回滚撤销。简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在MySQL中,事务支持是在引擎层实现的。 你现在知道,MySQL是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如MySQL原生的MyISAM引擎就不支持事务,这也是MyISAM被InnoDB取代的重要原因之一。事务有 下面几大特性:原子性,一致性,隔...

2019-12-05 17:45:46 461

原创 跳表

本节内容一下:由二分查找引出跳表什么是跳表如何实现跳表引出跳表二分查找:二分查找针对的是一个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。二分查找底层依赖数据结构:数组——即可以按照下标随机访问元素的数据结构二分查找的时间复杂度:O(logn)思考:一个有序的链表如何快速查找...

2019-11-12 12:01:38 105

原创 内存泄漏优化

内存泄漏:用动态存储分配函数开辟的空间,在使用完之后没有释放这块内存单元,直到程序结束。说白了就是对象使用完了,没有及时回收这个对象占用的内存空间。内存泄漏的危害如果一直不回收内存,那么可用内存就会越来越少,程序效率就会降低,最后造成内存溢出,然后程序就会崩掉。在android开发中,最容易引发内存泄漏的就是Context,你如Activity的Context,因为它包含大量的引用,一旦泄...

2019-09-09 12:57:05 144

原创 ReentrantLock与Condition讲解

ReentrantLockReentrantLock是可重入的独占锁实际上还是通过同步抽象队列实现的。它里面就是维护的一个state状态值。在默认的情况下,state的值为0,表示当前锁没有被任何线程占有。当一个线程第一次获取该锁的时候,会尝试使用CAS来设置state的值为1,如果CAS成功,那么当前线程就获取该锁,然后记录该锁的持有者为当前线程。在该线程没有释放锁的情况下尝试第二次获取,状态...

2019-09-08 16:27:40 357

原创 HandlerThread与IntentService

HandlerThreadHandlerThread是Android API提供的一个方便、便捷的类,使用它我们可以快速的创建一个带有Looper的线程。Looper可以用来创建Handler实例。它继承Thread,外界需要通过Handler的消息方法来通知HandlerThread执行一个具体任务。使用步骤1.创建HandlerThread线程2.运行线程3.获取HandlerThr...

2019-09-08 13:30:11 215

原创 java基础——抽象方法,抽象类和接口

一、抽象方法有关键字abstract修饰的方法是抽象方法。这类方法没有方法体。二、抽象类含有抽象方法的类是抽象类。如果一个类含有抽象方法,但是不声明为抽象类,那么会编译出错。注意:1.因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。如果使用抽象类创建对象就要实现里面的抽象方法。2.类中抽象方法必须为public或者protected(因为如果为pri...

2019-08-08 16:40:35 206

原创 String,StringBuffer,StringBuilder区别

初了解:String是字符串常量,是不可改变的,对该字符串操作都会产生一个新的字符串常量。StringBuffer和StringBuilder(JDK5.0之后)是字符串变量,每次操作是对本身的字符串操作,前者是线程安全,后者是线程不安全,由这点可以知道,前者的效率会比后者的效率低。详细解析:String:由于每次String是不可变对象,因此每一次都会操作都会产生新的S...

2019-05-19 14:42:46 172

OpenCV官方教程中文版(For Python).pdf

这是一个opencv的文档,翻译比较全,有需要的可以下载。是python语言的,其他语言的可以自己参考函数。

2019-12-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除