自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

ZH的博客

路漫漫其修远兮,吾将上下而求索。

  • 博客(52)
  • 收藏
  • 关注

原创 Kotlin协程基础

Kotlin协程是用JVM线程实现的,并没有改变线程的本质。它所提供的API也都可以使用线程的方式进行实现。但是实际开发中,通常来说没有时间和精力,或者有这个水平来做高性能的并发优化。Kotlin帮助我们做了优化,只需要使用它提供的API就能实现高效的并发编程。协程用更加直观的代码结构,做到了线程方式需要用复杂的回调才能做到的事,这就是Kotlin协程真正的优势。

2026-07-05 20:08:06 108

原创 Kotlin函数

在Kotlin中object是一个关键词,使用它修饰一个类,替换掉class关键字,表示创建一个类,并创建一个这个类的对象,实际上就是一个单例。它的原理就是这个参数除了被当做函数参数之外,Kotlin还会帮我们在类里自动创建一个和参数同名的属性,并把这个参数的值作为属性的初始值。这样写的属性和函数,不属于任何class而是属于package,它跟静态变量和方法一样,是全局的,而且用起来更加方便,连类名都不需要写,直接用就可以。lambda也是函数类型对象,它和匿名函数是同样的用法,可以理解为是同样的东西。

2026-07-05 20:07:42 132

原创 Translation & MotionLayout

被接管的布局,即是当前展示的布局。1、<OnClick>标签描述点击事件,其中targetId属性指定点击事件作用在哪个控件,clickAction属性定义点击时要执行的操作,常用的toggle值,表示当前处于开始状态,请将动画效果切换为结束状态;当然这里举的是简单的属性动画例子,实际上像缩放、平移、旋转等都可以用过渡动画实现,只需要指定修改的属性,不需要像属性动画那样,计算变化的高度、宽度、距离、角度等。可以传递整个xml文件,分别传递开始场景和结束场景的布局文件,就可以实现两个布局切换的过渡动画。

2026-07-05 20:07:05 142

原创 Drawable和Bitmap的区别

b、否则,先创建一个bitmap,给drawable设置边界范围(调用drawable的draw方法前,需要设置范围,不设置的话默认是空的范围),调用draw方法,把像素绘制到bitmap上,最后将bitmap返回。Drawable的绘制,是在draw方法里,执行绘制的代码。我们在绘制复杂view时,可以将绘制工作进行拆解,搬到drawable里面,降低绘制的复杂度,也方便对于需要重复绘制的部分进行重用。Bitmap是图象像素信息的存储工具,而Drawable是绘制的代码,表达的是绘制规则。

2026-07-05 20:06:49 140

原创 Java泛型详解

通过字段、方法的反射方法:field.getGenericType()、method.getGenericRenturType()、method.getGenericParameterTypes()可以分别获取字段的泛型类型、方法的泛型返回值类型、方法的泛型参数类型。这样再调用就没有问题。extends”限定符,它的作用是放宽声明变量时的要求,让子类类型的泛型对象可以赋值给父类类型泛型的引用。泛型从本质上来说,是做一个通用的功能,可以锁定类型,但是现在先不锁定,等到实例化它的时候在进行类型的确认锁定。

2026-07-05 20:06:34 176

原创 Rxjava

Rxjava有非常多的操作,我们只解析主要的几个:create、map、subscribe,以及切换线程的subscribeOn和observeOn方法的实现原理。让我们通过对RxJava的使用以及对框架的解析,理解这种不同于以往的编程思想。响应式编程是一种编程思想,一个起点和一个终点,事件从起点开始,中间有多个拦截,对事件进行处理,最终事件会流向终点,被终点消费掉。ObservableMap的内部类MapObserver的onNext方法,会回调我们重写的apply方法,完成数据变化。

2026-07-04 09:16:53 121

原创 APP启动优化

向上表示调用的层次,即下方的方法,调用执行上面的方法,因此图形越像上越窄,看上去像火焰的形状,因而也被称为“火焰图”。将这些任务同时启动起来,闭锁计数为0的可以直接执行,当执行完成后,将被它所依赖的任务的闭锁计数减1,当一个任务的闭锁计数为0就可以自动执行起来,如此往复循环。因为这里是采用inflate的方式,解析布局文件,并利用反射来创建View,这个过程是十分耗时的。这个图示,实际上是一个调用顺序表,最上面的最顶层的函数,向下是它调用的方法,这个表会统计每个函数执行的时间,执行占用百分比等。

2026-07-04 09:15:07 110

原创 APK瘦身

应用安装包过大会导致应用的安装、启动耗时增加,也会导致应用在使用时占用的内存大以及产生耗电问题。本文介绍应用安装包的结构,以及常用的包体积优化方法及原理。

2026-07-04 09:13:39 150

原创 Android Gesture Detector工具

我们知道Android中的事件,实际是一个事件序列,由一个Down事件、若干个Move事件,以及一个Up或Cancel事件组成。我们之所以能够区别长按、单击、双击、滑动等,都是通过对这个事件序列进行解析之后得到的。如Down事件之后500ms之内抬起(Up事件),则解析为单击;Down事件之后超过500ms抬起,触发长按。这种将事件序列解析为具体的行为的工作就是手势侦测。

2026-07-04 09:11:47 147

原创 图形工具Xfermode介绍

Xfermode是用于两张图片进行融合的技术。它实际上应该是transfermode,因为一些美国人习惯省事把“trans”读作“X”。它实际上是Paint类一个方法的参数,指定接下来按照融合的方式进行绘制。setXfermode这个方法的参数本来有三种,其余两种已经被遗弃的状态,现在只剩下一种,就是PorterDuffXfermode。它是用发明它的两个人的名字Porter和Duff定义的名称。PorterDuffXfermode提供15中融合方式。原图和目标图:2、将方形图片绘制成圆形。

2026-07-04 09:11:10 149

原创 约束布局详解

布局优化是我们在开发中常常遇到的问题。我们知道布局越复杂嵌套层次越深则加载它的开销越大,性能越差。约束布局是我们在进行布局优化时经常会考虑使用的方式。约束布局不仅提供了一些如百分比布局、角度定位、辅助线等一些好用的工具,帮助我们可以轻松实现一些效果。最主要的是,它使得布局扁平化,减少了布局的层次,从而提升了加载布局的效率。

2026-07-03 19:17:20 108

原创 Android Handler机制

主线程是不可以退出的。上面我们对于Handler原理的分析,知道在MessageQueue中没有消息在处理的时候,会调用底层的方法进入沉睡状态。之所以我们应用程序能够一直存在,主要是因为在Looper.loop函数里面会执行一个无限的for循环,周而复始的处理消息,让Android程序持续存活并完成各种功能。通常上层在调用postSyncBarrier,会开始插入异步消息,插入异步消息的方法,就是插入一个普通消息,调用这个消息的setAsynchronous(true)将它变成一个异步消息。

2026-07-03 19:14:47 127

原创 Activity启动模式

Activity的四种启动模式,主要围绕任务启动和任务切换的问题,目的是为了更加精准的可控的界面导航。SingleTop 和 Standard定义的是在当前栈打开的行为。而singleTask和singleInstance则是定义跨Task打开的行为,展现跨Task交互的意图。实际使用上,standard和singleTop多在app内部使用;singleInstance比较多用于定义给开放出来给其他app共享使用的activity;SingleTask内部交互和外部共享都适用。

2026-07-03 19:13:21 134

原创 View触摸反馈与事件分发原理

如果子View不消费,则传递到它下层的子View,继续做同样的判断,如果所有子view都不消费。View的原生事件处理主要做几件事情,结合手指的按下、移动、抬起一系列的动作,进行“点击”、“长按”、“显示TOOLTIP”,以及“是否进行滑动”的检查。我们看到上面进行事件拦截判断时,当MOVE事件过来,已经有子view处理在处理该事件序列时,可以通过设置FLAG_DISALLOW_INTERCEPT允许父view拦截,然后父view的onIntercepTouchEvent()方法返回true。

2026-07-03 19:12:02 159

原创 自定义View之文字测量原理与文字特效实现

本文详细介绍了Android自定义View中文字绘制的关键技术与常见问题解决方案。首先解析了文字测量原理,包括baseline、ascent/descent等概念,解决了文字居中和贴边显示不准确的问题。然后讲解了多行文字绘制方法,包括使用StaticLayout和自定义换行逻辑。最后以歌词效果为例,演示了文字渐变效果的实现原理——通过分层绘制和剪裁控制。文章提供了文字贴边、垂直居中、动态换行等实用技巧,并附有实现思路和效果图示,帮助开发者掌握精细化文字绘制技术。文末还提供了文字绘制知识体系的思维导图参考。

2026-07-03 19:00:30 195

原创 NestedScrollView实现嵌套滑动机制

本文介绍一种常用的实现嵌套滑动的开源框架NestedScrollView。通过它可以优雅的实现嵌套滑动的效果。

2024-09-26 19:35:52 2243 2

原创 属性动画与硬件加速

在屏幕显示的时候,GPU拿着cpu的指令,直接转换为像素应用到屏幕上,显示文字,图形等元素。本文根据动画常见的使用场景,详细总结一下Android中各种属性动画的区别和特点,以及制作复杂动画所用到的关键帧、插值器、估值器的原理、使用场景和方法。view的绘制是非常频繁的操作。为了性能考虑,android每次绘制信号到来(就是我们常说的VSync信号),并不会整个界面,只绘制改变了的区域。它的主要原理是,这些view自带的属性,被android做了优化,这些属性的改变,不会导致gpu操作的改变。

2024-06-23 21:43:26 980

原创 Grdle构建原理分析

它的作用是包住gradle,实际上做工作的是它里面的gradle。java语言提供匿名内部类和lamda表达式的形式来传递方法,它实际上传递的是类的对象,而不是方法本身。前面说的buildType flavorDimensions生成的变体,实际上是通过插件根据配置创建出不同的task(后面准备分享一票Android apk编译打包的过程,这里再详细进行介绍)。事实上,老的版本Gradle只提供compile方法,新的版本提供了非传递依赖的implementation方法和传递依赖的api方法。

2024-06-23 21:40:21 1078

原创 (三)OkHttp网络请求拦截器详解

这个拦截器一般做网络调试用,用户自定义,插在连接拦截器和请求服务拦截器之间。整个OkHttp的网络请求工作都是在这个五大拦截器中完成。他们分别负责不同的工作,如果流水线一样,经过五到工序,最终完成了完整的工作。

2023-08-06 08:54:05 3552

原创 (二)OkHttp网络请求配置参数详解

前面说到OkHttp网络请求的总体框架。这一章节主要通过解读OkHttpClient的内容,了解可以通过框架配置哪些参数,以及这些参数的意义。让我们对OkHttp框架和HTTP协议之间的关系有更深的了解。

2023-08-06 08:50:03 4569

原创 (一)OkHttp网路请求框架详解

前面几篇文章讲解了HTTP相关的技术知识。接下来将看一下OkHttp是如何使用HTTP的相关技术,完成网络请求。如果没有看过之前HTTP的内容,建议先看一下再来看本章的内容。本文是介绍OkHttp的第一章节----OkHttp的网络请求框架。

2023-08-06 08:46:10 1321

原创 View的加载和更新流程

本文主要讲解View的完整加载过程和View的更新流程。

2023-08-06 08:44:47 709

原创 Git深入理解与常用操作的本质

Git当前十分流行的版本管理系统(VCS)。它是一种分布式的VCS,即Git的每一个仓库都具有完整的内容和功能,可以独立运行。基于分布式的特性,Git可以在任意位置clone代码仓库,进行开发和提交。使得对代码的管理十分方便。本文对Git涉及的主要概念以及经常会用到的Git命令进行讲解。帮助大家更好的理解、掌握和使用Git。本文篇幅较长,请耐心阅读。

2023-05-20 09:30:15 624

原创 Dagger2实现原理分析

Dagger是一个依赖注入框架,这个框架往往给人一种“高端,但是却很难用“的感觉。我们在使用或者阅读别人的项目时,往往会陷入dagger搭建的”迷宫里”绕不出来。导致Dagger被认为是android史上”最受冷落的优质库”。本文先通过理清依赖注入的概念,然后详细介绍Dagger一些常见的使用场景和注意事项,最后介绍一下Dagger主要功能实现的原理。帮助大家进行理解。

2023-05-20 09:20:02 1652 1

原创 HTTPS安全通讯原理解析

对于敏感数据我们通常会选择用HTTPS进行加密传输。HTTPS和HTTP有什么关系?它是如何实现数据安全传输的?现在就带你研究。

2023-03-04 14:12:25 364

原创 一文读懂TCP/IP网络分层模型

网络模型有国际标准化组织定义的OSI七层网络模型和实际使用的TCP/IP五层网络模型。本文从应用开发的角度介绍TCP/IP网络模型,帮助大家更好的理解。

2023-03-04 14:11:19 827

原创 HTTP登录和授权

HTTP是无状态的协议,它不会记录和保存之前连接的状态。那么它进行登录验证和授予客户端权限的过程是怎样的?我们经常使用微信、QQ等进行第三方的授权登录。又是怎样实现的?本文将通过介绍HTTP登录和授权机制帮助大家理解这些问题。

2023-03-04 14:10:07 2292

原创 网络安全签名与认证

网络安全的签名与认证是非常实用的技术知识,但是了解的人比较少。因为相关的内容基本都有成熟的解决方案,很少需要我们做什么。这些东西经常被用到,需要真正理解才能更好和更正确的使用。这里把相关的内容整理出来,帮助大家更好的掌握。

2023-03-04 14:06:27 982

原创 HTTP工作方式与报文解析

HTTP是我们在开发工作中经常接触而又容易被忽视的知识点。它经常是“一次配置,终身使用”。即在第一次被搭建起来,后面基本不会再动它。前端、后端,以及前后端交互的代码都已经定型。而我们只需要按照之前的规则来对他进行扩展。这就导致了我们经常使用,但对它又并不是很了解。本文将通过介绍HTTP协议的定义、工作方式,以及请求报文和响应报文的解析,帮助大家更好的理解HTTP协议。

2023-03-04 14:04:25 1205

原创 Java原生网络编程 ---- IO多路复用

Java是在jdk1.4引入支持NIO的库。前面博客说过BIO通讯,这种模式下服务端一个线程只处理一个会话。当线程被阻塞在read() 或 write()时,不能够做其他的事情。线程在服务器属于比较昂贵的资源。BIO的方式会造成很大的资源浪费。NIO,被称为IO多路复用,中心思想既是对服务器的线程进行复用,从而提高服务器资源利用的效率。

2022-05-14 17:00:00 2217 1

原创 Java原生网络编程 ---- 阻塞式IO

阻塞式IO,即BIO。采用BIO通信的服务端模型,通常由一个独立的Acceptor线程负责监听客户端的连接,当收到一个客户端连接请求后,为该客户端创建一个线程进行会话,包括数据的读取、写入以及处理等,会话完成后销毁线程。这是一种“一请求一应答”的模型,即一个线程处理一个会话。

2022-05-14 13:00:00 502

原创 HTTP协议简介

HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写,用于从万维网服务器传输超文本到本地浏览器。(本地浏览器通过解析超文本从而在本地浏览器显示内容)。HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息。URL,全称是UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地...

2022-05-14 10:00:00 874

原创 TCP协议

TCP(Transmission Control Protocol)是面向连接的可靠的通讯协议。TCP需要经过三次握手建立连接,并在断开时通过四次挥手释放连接。TCP通过应答确认、超时重传(RTO)、往返时延(RTT)、数据排序、流量控制、全双工通讯的机制和特性,保证连接的可靠性。

2022-05-13 01:15:00 2474

原创 Java原生网络编程基础

计算机网络,是利用通信线路将地理上分散的、具有独立功能的计算机系统和通信设备按不同的形式连接起来,以功能完善的网络软件及协议实现资源共享和信息传递的系统。

2022-05-12 23:45:00 231

原创 Java外置锁实现原理

Java中的锁,如,ReentrantLock(显式锁)、CountDownLatch(闭锁)等都是基于AQS(队列同步器)来实现的,AQS又是CLH队列锁的一种变体实现。下面对这些锁的知识进行详细介绍。

2022-05-12 02:15:00 205

原创 CAS原理与无锁化编程

在前面的博客“sychonized锁升级机制”中提到过CAS自旋锁。他的全称是Compare And Swap,翻译成“比较和交换”。是一种轻量级的基于轮询的并发工具。CAS原理CAS操作过程都包含三个运算符:一个内存地址V,一个期望的值A和一个新值B。操作的时候,如果该地址上存放的值等于这个期望的值A,则将地址上的值赋为新值B;如果地址上的值和期望值A不相等,则不进行操作,从新获取旧值A和计算新值B后,再次进行上述操作。如此循环直到操作成功位置。在这个过程中,比较...

2022-05-12 00:30:00 441

原创 并发编程工具 ---- 阻塞队列

阻塞队列,是只支持阻塞方式插入、移除方法的队列。支持阻塞的插入,即是当队列满时,队列会阻塞插入元素的线程,直到队列不满;支持阻塞的移除,是在队列为空时,获取元素的线程会阻塞等待队列变为非空。队列队列是线性表的一种,但是他是一种受限的线性表,只允许在表的前端(front)进行删除操作,又称为出队;在表的后端(rear)进行插入操作,又称为入队。进行插入的一端称为队尾,进行删除的一端称为队头。队列的这种特性,导致最早进入队列的元素最先从队列中删除,因此队列又称为先进先出(...

2022-05-11 02:00:00 186

原创 线程池工作原理

Java的线程池是当前应用最普遍的一种并发框架。在并发编程中,合理的使用线程池能够带来一系列的好处。1、降低资源消耗。线程池通过重复利用已创建的线程,从而降低线程创建和销毁的开销;2、提高响应速度。当任务到达时,任务可以不用等待创建线程,利用现成的线程资源就能立即执行。例如,完成一项任务需要时间分为:T1线程创建的时间,T2在线程中执行的时间,T3线程销毁的时间。线程池通过把T1、T3安排在空闲的时间执行。在有任务提交过来时,只消耗了T2执行任务的时间...

2022-05-11 00:45:00 1524

原创 ThreadLocal实现原理

ThreadLocal和其他并发工具一样,也是用于解决多线程并发訪问。ThreadLocal通过为每个线程都提供了变量的副本,使得每个线程在同一时间访问的并非同一个数据,从而隔离了多个线程对数据的数据共享。ThreadLocal的使用ThreadLocal 类接口只提供了4个方法:public void set(Object value),设置当前线程的线程局部变量的值。public Object get(),该方法返回当前线程...

2022-05-10 01:00:00 2828

原创 Volatile关键字与可见性问题

Java内存模型(JMM)Java内存模型,既是定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。其中,JMM隶属于JVM。JMM主要解决的问题,是处理cpu处理速度和内存存取速度极度不平衡的问题。以下数据摘自《Jeff Dean在Google全体工程大会的报告》。根据表格中的数据,计算从内存中读取1M的int型数据由CPU进行累加的耗时情况。Java里int型为32位,4个字节,1M数据共有1024*1024/4 = 262,144个整数 ,CPU...

2022-05-10 00:15:00 206

空空如也

空空如也

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

TA关注的人

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