自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(33)
  • 收藏
  • 关注

原创 okhttp 源码分析

之前分析了 okhttp 的缓存拦截器 CacheInterceptor 的实现机制,这次再来详细分析一下 okhttp 的工作流程和其他拦截器。先看一下工作流程(本文基于 4.9.3)

2022-08-19 16:09:13 1078 2

原创 SharedPreferences 源码分析

SharedPreferences 是系统提供的一个适合用于存储少量键值对数据的持久化存储方案,特点是 API 比较简单使用比较方便,但它也有一些缺陷如果使用不当可能会导致卡顿甚至是 ANR 并且 SharedPreferences 不支持多进程...

2022-07-05 16:34:19 435

原创 View 工作流程

任何控件的展示都是通过 WindowManager.addView 来实现的并且 WindowManager 是一个接口真正的实现是 WindowManagerImpl 它又直接调用了 WindowManagerGlobal 的 addView 方法在这个方法里创建了 ViewRootImpl 它是所有控件的抽象父控件,它没有不是继承自 View 但是实现了 ViewParent 接口是 DecorView 的 parent,在 Activity 中通过 setContentView 方法传入的布局就是设置

2022-06-29 18:25:38 521

原创 Savedstate 源码分析

Android 应用在被进程可通过 onSaveInstanceState-onRestoreInstanceState 保存一些必要数据用于在页面重建时恢复页面 savedstate 对此进行了封装,它与 ViewModel 的区别:SavedStateHandle 的引入使得开发者无需直接使用 onSaveInstanceState(Bundle) 等方法来完.

2022-05-03 17:21:50 312

原创 ViewModel 源码分析

ViewModel 是 Jetpack 组件之一,能力是维护数据保证在因配置更改导致的页面重建时 ViewModel 可以存活下来,另外使用 ViewModel 可以很方便的在一个 Activity 的多个 Fragment 中共享数据

2022-04-30 16:56:50 1431

原创 LiveData 源码分析

LiveData 是 Jetpack 的组件之一,是一个可感知目标生命周期并且可被观察的数据容器,当容器内数据变化时会根据观察者是否处于活跃状态回调最新数据给观察者,当观察者从非活跃状态变为活跃状态时同样会回调最新数据给观察者,并且当所属组件生命周期变为 DESTROYED 状态时会自动移除观察者避免内存泄漏,下面来分析一下 LiveData 的源码提示:以下是本篇文章正文内容,下面案例可供参考

2022-04-16 16:14:04 2152

原创 Retrofit 源码分析

Retrofit 是 square 公司出品的基于 okhttp 的适用于 Android 和 JVM 的类型安全的 HTTP 客户端,它对网络请求进行了封装真正发起网络请求的还是 okhttp 拿到响应之后再转发给 retrofit

2022-04-01 01:02:58 64

原创 Lifecycle 源码分析

前言Lifecycle 是 Jetpack 的一员同时也是 LiveData 和 ViewModel 的基础,之前只是看过大概原理,今天来细读一下源码二、主要成员LifecycleOwner 是一个接口用于被观察的组件实现,唯一一个方法用于返回一个 Lifecycle 对象,实现它的对象表示具有生命周期Lifecycle 是一个抽象类,三个抽象方法分别用于添加、移除观察者和获取组件(具.

2022-03-19 15:46:06 3120

原创 Android 屏幕刷新机制

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言Android 4.1 Jelly Bean 推出了 Project Butter 用于解决 Android 系统一直以来的 UI 流畅性问题。引入了三个核心元素,即VSYNC、Triple Buffer和Choreographer。其中,VSYNC是理解Project Buffer的核心。VSYNC是Vertical Synchronization(垂直同

2022-03-03 00:10:40 1180

原创 Android MultiDex 源码分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、启动 MultiDexAndroid 5.0 和之后的版本Android 5.0 之前的版本二、MultiDex 的限制三、在主 dex 文件中包含必要的类四、源码分析二、使用步骤1.引入库2.读入数据总结前言App 在迭代过程中功能越来越丰富,代码量越来越多就会遇到一个构建错误表示方法数超出 65536 出现这个问题的原因是 dex 文件中对方法数的索引是 short 类型。在计算机科学领域,术语 K 表示1024(

2022-02-02 18:24:22 2564

原创 Android 混淆

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、ProGuard、DX、D8、R8二、使用步骤1.引入库2.读入数据总结前言Android 应用在发布时一般都会做代码混淆,具体就是在 build.gradle 中配置minifyEnabled true作用一是增加反编译的难度,二是缩减应用大小,下面来看一下混淆的具体原理提示:以下是本篇文章正文内容一、ProGuard、DX、D8、R8在上面 Android 打包流程图中会把项目和依赖库中的 Clas

2022-01-24 15:43:09 2079

原创 关于 Toast 的两个问题分析和解决方案

一、WindowManager.BadTokenExceptionToast 在 Android API 25 上有几率会抛出这个异常 override fun onCreate(savedInstanceS

2022-01-02 18:14:50 1561

原创 Glide 加载图片流程和缓存机制(下)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言总结前言上篇可能因为字数限制不能继续编辑了所以分为了两篇提示:以下是本篇文章正文内容上篇说到 com.bumptech.glide.load.engine.DataCacheGenerator#startNext 这里会拿到多个ModelLoader 第一个是 ByteBufferFileLoader 它的 DataFetcher 是 ByteBufferFetcher 看下它的 loadData publ

2021-12-20 14:37:14 1624

原创 Glide 加载图片流程和缓存机制(上)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、Glide 缓存1. 内存缓存2. 磁盘缓存二、源码分析2.读入数据总结前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。本文基于 Glide 4.8.0一、Glide 缓存Glide 的缓存机制非常精细范围内存缓存和磁盘缓存,内存缓存又包括活动资源 (Active Resources) 和内存缓

2021-12-20 14:36:47 253

原创 okhttp 缓存分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例可供参考一、pandas是什么?示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。二、使用步骤1.引入库代码

2021-11-05 17:55:05 135

原创 ThreadLocal 源码分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结参考前言ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据。虽然在不同线程中访问的是同一个 ThreadLocal 对象,但是它们通过 ThreadLocal 获取到的值却是不一样的。一般来说,当某些数据是以线程为作用域并且不同线程具有不同

2021-10-24 17:50:23 59

原创 浅析 Java 线程池

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

2021-10-20 18:06:34 113

原创 浅析 Https

Http 的缺点?1.1 通信使用明文可能会被窃听1.2 不验证通信方的身份就可能遭遇伪装1.3 无法验证报文完整性可能已遭篡改二、SSL 和 TLS三、Https3.1 加密3.11 对称加密3.12 非对称加密3.2 数字签名3.3 数字证书2.读入数据参考前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础......

2021-10-14 21:26:26 189

原创 LinkedHashMap 源码分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、accessOrder二、linkNodeLast2.afterNodeAccess3.afterNodeInsertion4.afterNodeRemoval三、LruCache总结前言HashMap 不是有序的当需要保持元素的顺序时就可以使用 LinkedHashMap 它支持维护两种顺序,插入顺序和访问顺序(可用于实现 Lru 算法),LinkedHashMap 是 HashMap 的子类所以原理相同只不过 Li

2021-10-09 10:54:36 80

原创 ArrayMap 源码分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、ArrayMap 是什么 ?二、源码分析1. 主要成员2. 缓存机制2.1 freeArrays2.1 allocArrays总结一、ArrayMap 是什么 ?ArrayMap 跟 HashMap 一样实现了 Map 接口所以也是存储键值对结构的数据容器,但是存储元素的方式不 HashMap 不太一样,ArrayMap 使用两个数组,一个 int 数组用于保存所有 key 的 hash 值,一个 Object 数组保存所

2021-10-08 16:31:04 67

原创 SparseArray 源码分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、SparseArray 是什么 ?二、源码分析1.delete2.put3.append4.get5.其他三、最后参考前言因为泛型擦除的原因基本数据类型不能作为泛型参数,如果需要就得使用它们的包装类就带来了装箱拆箱的开销,为了解决这个问题才有了 SparseArray 相关的几个类,SparseArray 比 HashMap 要慢一些是时间换空间的实现。提示:基于 Android SDK 28一、SparseAr

2021-10-06 15:11:46 114

原创 HashMap 源码分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、哈希表1.什么是哈希表2.什么是哈希冲突3.如何处理哈希冲突4.链地址法的缺点二、equals 与 hashCode 函数的关系三、负载因子四、HashMap2.读入数据总结一、哈希表1.什么是哈希表哈希表又叫散列表,是一种根据设定的映射函数f(key)将一组关键字映射到一个有限且连续的地址区间上,并以关键字在地址区间中的“像”作为元素在表中的存储位置的一种数据结构。这个映射过程称为哈希造表或者散列,这个映射函数f(ke

2021-09-29 23:26:37 65

原创 RxJava简介

本文基于RxJava2.2.2。基本概念RxJava是Reactive Extensions的Java VM实现:一个用于通过使用可观察序列来编写异步和基于事件的程序的库。Reactive Extensions:http://reactivex.io/intro.html我的理解,Rx是一个标准,一个原则,RxJava则是一个这种标准原则在java上的应用库。Cold Observab...

2018-10-07 19:15:19 207

原创 浅析RxJava2线程切换

RxJava2中有两个可以切换线程的操作符,subscribeOn和observeOn。它们有什么区别,如果分别使用多次,会是什么结果。先说结论:observeOn() 关注的是在它之后的操作,调用多次则切换多次线程。subscribeOn() 只有最开始的一次起作用,如果调用多次,只是创建了线程,它去通知它的上游的动作是在这个线程里,但最后onXxx()的动作还是在第一次调用的线程里。/...

2018-10-07 14:37:51 452

原创 《Android源码设计模式》读书笔记——单例模式

定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例使用场景:确保某个类只有一个对象,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有一个。例如创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源,这时就要考虑使用单例模式。 《Effective Java》中提到要不要使用单例取决于,这个类的所有实例在功能上都是相互等价的。关键点:1,构造...

2018-08-16 09:26:46 173

原创 Android 事件分发

所谓事件分发,就是对MotionEvent的分发过程,当一个MotionEvent产生了以后,系统需要把这个事件传递给一个具体的View,而这个传递的过程就是分发过程。引用一个《Android开发艺术探索》里的概念: 同一个事件序列是指手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束,在这个工程中所产生的一系列事件,这个事件序列以down事件开始,中间含有数量不定的move事件,最终以u...

2018-04-21 12:28:00 214

原创 浅析setContentView

Activity使用setContentView来展示一个布局,我们来看一下流程 @Override public void setContentView(View view) { getDelegate().setContentView(view); }可以看到这里使用委托机制,使用AppCompatDelegate去处理 @NonN...

2018-04-11 21:37:56 99

原创 浅析LayoutInflater

浅析LayoutInflaterLayoutInflater用来加载一个布局,首先使用下面的方法获取LayoutInflater对象LayoutInflater LayoutInflater =(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);这里的context通常是Activit...

2018-04-08 21:56:02 123

原创 Effective Java 读书笔记

1.考虑用静态工厂方法代替构造器静态工厂方法与构造器不同的第三大优势在于,他们可以返回原返回类型的任何子类型2.遇到多个构造器参数时要考虑用构建器3.用私有构造器或者枚举类型强化Singleton属性单元素的枚举类型已经成为实现Singleton的最佳方法4.通过私有构造器强化不可实例化的能力5.避免创建不必要的对象6.消除过期的对象引用(这里可以给个例子)7.避免使用终结方法final

2017-08-01 21:54:37 262

原创 Android动画实例 (二)

效果图实现思路 循环添加一个自定义的ImageView,每个ImageView随机设置不同颜色的Bitmap,并且有一个放大的动画,比较简单。然后ImageView的移动轨迹使用贝塞尔曲线来完成。最后一个缩小到动画,动画结束移除控件。public HeartView(Context context, AttributeSet attrs, int defStyleAttr) { sup

2017-06-09 00:37:34 270 1

原创 Android动画实例 (一)

效果图 比较简单,就是一个控制绘制小球的坐标变化,再加上一个底部阴影的效果(效果出来了,不够好看)实现思路 刚看到效果的时候,想着用两个个动画组合实现 一个小球升起落下的动画 一个小球从圆变成椭圆的动画 再加上一个底部阴影线的绘制的缩放动画 再实现过程过程中发现第一个动画和第二个动画之间不连贯,圆变成椭圆之间有停顿,即使第一个动画开始之后立即开始第二个动画,然后突然想到直接改成绘制椭

2017-06-08 17:41:25 321

原创 Thinking in Java 读书笔记 (二)

RTTI和反射枚举注解并发死锁ReadWriteLockCountDownLatchCyclicBarrierExchanger免锁容器泛型RTTI和反射 在Java中,所有的类型转换都是在运行时进行正确性检查的。这也是RTTI名字的含义:在运行时,识别一个对象的类型。所有的类都是在对其第一次使用时,动态加载到JVM中的。当程序创建第一个对类的静态成员的引用时,就会加载这个类

2017-06-07 23:38:42 245

原创 Thinking in Java 读书笔记 (一)

欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:System.arrayCopySetMapBitSet序列化String formatByteBufferFileLock持久化RTTI和反射枚举注解并发死锁ReadWriteLockCountDownLatchCyclicBarrier

2017-06-07 23:27:04 280

空空如也

空空如也

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

TA关注的人

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