自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Jetpack-LiveData原理补充

当Fragment2点击返回回到Fragment1时Fragment1又执行了onCreateView()生命周期,这样在onCreateView()到onDestroyView()之间执行的LiveData数据观察者绑定又被执行了一次,此时又由于每次observe时绑定的Observer对象都不是同一个就会导致同一个LiveData其实是被重复绑定了数据观察者。而Fragment则是在performDestroy()方法中也就是onDestroyView()之后onDestroy()之前才执行。

2022-09-16 18:11:37 539 1

原创 Jetpack-LiveData

LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如activity、fragment或service)的生命周期。这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。如果观察者(由 Observer类表示)的生命周期处于STARTED或RESUMED状态,则LiveData会认为该观察者处于活跃状态。LiveData只会将更新通知给活跃的观察者。

2022-09-16 18:06:25 760

原创 Jetpack-ViewModel

ViewModel是Android Jetpack库中的一员,旨在以注重生命周期的方式存储和管理界面相关的数据。其与生命周期强相关。在组件(Activity/Fragment)的生命周期中ViewModel的数据会一直保存在内存中,即便在组件发生重建时(例如当Activity屏幕旋转或者设置改变等原因导致的页面重建)也会一直存在。ViewModel可以实现组件之间的数据共享,主要是通过使用相同的ViewModelStore来进行共享。

2022-09-06 15:13:41 780

原创 Jetpack-Lifecycle

lifecycle的设计其实非常简单,就是一个典型的观察者模式。假设让我们用自己的思路实现一个最简单的监测Activity生命周期的观察者,动手之前思考一下观察者模式必备的几个角色:**1.被观察者**,**2.观察者**,**3.调度类(管理观察者和被观察者之间关系)**。

2022-08-23 15:54:36 612

原创 Android小知识- LayoutInflater

infalte()中root为空则返回的是xml布局对应的view,此时view没有任何布局参数,也并未被添加到容器中infalte()中root不为空,则判断attachToRoot == true返回的是root,attachToRoot == false返回的是xml布局对应的view,和第1点一样如果inflate传递的资源id是个merge标签,则root不能为空,attachToParent必须是true,对应的merge下的view会被添加到root容器中。

2022-08-19 10:53:48 654

原创 Android小知识-HandlerThread

如果你在开发android项目时想实现一个带消息队列的子线程,那我建议你不要重复造轮子,你可以看看HandlerThread这个类,它就是系统封装好的一个很好用的带消息队列的子线程。其实HandlerThread只是系统对子线程开发需求的一个小封装而已,但是我个人觉得挺实用的。上面代码中的注释已经很详细的说明了HandlerThread的原理,结合它的使用方式看源码应该是一目了然了。Android线程间通信主要方式是使用Handler相信没有一个做Android的人不知道。...

2022-07-26 17:10:25 528

原创 binder(三)binder简介

前文binder(一)Linux必备知识篇已经了解过一些Linux相关的知识。因为Android是基于Linux内核的操作系统,所以Android也具备Linux进程隔离的特性。每个进程都是一块单独的内存单元,各个进程之间要互相通信需要一套IPC机制来实现。简单介绍一下Linux进程间通信方式。linux中主要的进程通信包括以下几种:以上是Linux进程间通信的几种主要方式,各种方式都有自己的优缺点,也有自己的擅长使用领域,可自行了解一下。在Android中主要是采用Binder来实现的。当然并不是说An

2022-07-04 15:30:20 294

原创 Android序列化之Parcel

Android操作系统的底层数据传输形式是简单的字节序列形式进行传递。用通俗的话说就是系统不认识对象,只认识字节序列。而我们为了达到通信或者存储的目的,需要先将数据序列化传递,要使用时再进行反序列化还原。我们知道Android系统是基于Linux系统实现的,而Linux有进程隔离的机制。而进程如果传递复杂数据类型那传递的是对象的引用,本质上就是一个内存地址。但是传递内存地址的方式在跨进程中明显不行,由于Linux采用了虚拟内存机制,两个进程都有自己独立的内存地址空间,所以把A进程中某个对象的内存地址传递给B

2022-06-27 16:44:41 2729

原创 最讨厌QA提按钮快速点击的bug了

首先声明:本库的编写是被QA逼出来的。在开发过程中经常被QA提一类恶心的bug(快速点击控件出现多个页面或多个弹窗等)我司QA拿到包之后第一件事就爱测快速点击的场景,他们认为同一个按钮快速点击可能是误操作不应该得到响应。比如某个按钮点击之后应该弹出一个dialog,QA双击控件就出现2个dialog。这原本应该是个正常的场景,但是奈何抵不过他们一直提,所以就做了这个小功能加以限制。其实这就是个典型的AOP编程了。屏蔽快速点击最常见的操作是做一个工具类:这样就能解决90%问题。奈何我司QA测得又比较细,某天

2022-06-23 19:45:37 603

原创 binder(三)mmap浅析(转载记录)

前言介绍 mmap 的文章很多,本文主要结合官方文档、之前看到的一些比较不错的文章进行一个总结。概念在计算机中,mmap 是 POSIX(Portable Operating System Interface of UNIX 可移植 UNIX 操作系统接口,制定了标准 API 接口规范) 兼容的 Unix 系统调用,可以将文件或设备映射到内存中,这是一种内存映射文件 I/O 的方法。实现了按需加载分页,不直接从磁盘读取文件内容,并且初始化时根本不使用物理 RAM。在访问特定位置后,以 lazy 方式从

2022-05-03 21:42:54 342

原创 binder(二)MMU浅析

什么是虚拟内存在现代的操作系统中,当你对内存地址进行操作时其实操作的并不是物理内存地址,而是系统虚拟出来的一个虚拟内存地址。通过简单的图例说明虚拟内存的概念。操作系统的物理内存是固定的,我们这里指的是RAM。当操作系统运行多个进程时,每个进程如果直接访问物理内存,那是不是就会出现你进程P1访问地址A时如果进程P2也访问该地址,那就会造成进程之间的冲突。所以当代操作系统引入了虚拟内存的概念。在创建P1和P2进程时,操作系统会分别告诉它们我整个内存都是你的,可是事实上操作系统给它们画了大饼,其实它们得

2022-05-03 21:30:06 1286

原创 binder(一)Linux必备知识篇

对linux操作系统中某些概念做简单预习,旨在为后续Android学习提供前提铺垫。例如学习binder、锁机制等等。软件程序管理Linux操作系统将运行中的程序成为进程。而Linux内核控制这Linux操作系统如何管理运行在系统上的所有进程。内核创建了第一个进程(init进程)来启动系统上所有其他进程。 当内核启动时,他会将init进程加载到虚拟内存中。内核在启动任何进程时都会在虚拟内存中为该进程分配一块专有区域用于存储该进程用到的数据和代码。进程隔离Linux中为每一个进程分配内存时都将内存

2022-04-21 18:47:31 2827

原创 装饰者设计模式

简述装饰者模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),以透明动态的方式来动态扩展对象的功能,也是继承关系的一种代替方案。Component:抽象组件(可以是抽象类或者接口),被装饰的原始对象ConcreteComponent:具体实现类,被装饰的具体对象Decorator:抽象装饰者,职责就是为了装饰我们的组件对象,内部一定要有一个指向组件对象的引用ConcreteDecoratorA:装饰者具体实现类,只对抽象装饰者做出具体实现Concret

2022-04-15 15:34:30 56

原创 Java泛型

泛型也叫“参数化类型”,是在java1.5之后才有的用法之所以出现泛型的最主要原因是能提高java程序的类型安全,使得当程序的类型转换错误能在提早得到暴露(将类型错误从运行时暴露提前到编译时)。假设不使用泛型,那么创建例如ArrayList这种容器类时如果想让该容器支持存储各种类型的数据则需要将ArrayList所能存储的数据定义为Object。假设存入时同一个容器存入了不同的数据类型,那么使用时很可能因为失误造成低级错误:public void test(){ ArrayList<O

2022-03-21 23:22:12 2595

原创 动态插桩技术以及动态类加载

运行时机原理图:class文件简介Java编译器编译好Java文件之后,产生.class 文件在磁盘中。这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码。JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象:class字节码文件是根据JVM虚拟机规范中规定的字节码组织规则生成的、具体class文件是怎样组织类信息的,可以参考 此博文:深入理解Java Class文件格式系列。或者是Java虚拟机规范。在运行期的

2022-03-21 16:45:32 407

原创 java锁机制 偏向锁-轻量级锁-重量级锁

首先粗略了解一下java对象的内存结构:紧接着看下Mark Word的内存结构(以下都用缩写MW代表Mark Word):再看下当一个对象被当成锁对象之后的内存结构变化:当对象处于无锁状态时没什么好说的,它并没有多线程的情况。当对象处于多线程环境下,我们往往是通过给对象加锁的做法来保证多线程操作共享变量的安全性,此时为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一。本文主要了解一个对象在多线程环境下的锁膨胀机制,大概就是无锁->偏向锁->轻量锁->重

2022-01-11 10:44:59 677 1

原创 Java锁机制之synchronized

java中2种锁的实现原理区别:synchronized: 在软件层面依赖JVM,在jvm将class文件编译成字节码文件时添加monitorenter和monitorexit句柄来区分加锁代码块Lock: 在硬件层面依赖特殊的CPU指令。synchronized机制:首先需要明确的一点是:Java多线程的锁都是基于对象的,Java中的每一个非空对象都可以作为一个锁。synchronized关键字锁具体表现为:锁对象和锁对象的class类;每个类可以有很多实例对象,不同实例对象的对象锁互不干扰,但

2022-01-08 22:26:05 3386 1

原创 Android23-app启动流程

源码版本Android 6.0请参阅:http://androidxref.com/6.0.1_r10本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟踪代码逻辑更清晰会省略掉一部分非主干的代码,具体详细代码请翻阅源码。暂时只上传分析之后的流程图,具体细节等有时间再写。本流程图表述了一个App从启动开始到执行Activity的onCreate()方法为止。...

2022-01-04 16:03:44 1068

原创 Android UI绘制流程分析(四)layout

源码版本Android 6.0请参阅:http://androidxref.com/6.0.1_r10本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟踪代码逻辑更清晰会省略掉一部分非主干的代码,具体详细代码请翻阅源码。上一篇我们分析到UI绘制过程中的measure流程,接下来我们来分析一下layout过程,layout过程相对于measure过程简单很多,还是从ViewRootImpl#performTraversals()方法调用performLayou

2021-12-24 11:22:38 82

原创 Android UI绘制流程分析(三)measure

源码版本Android 6.0请参阅:http://androidxref.com/6.0.1_r10本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟踪代码逻辑更清晰会省略掉一部分非主干的代码,具体详细代码请翻阅源码。在上一篇文章Android UI绘制流程分析(二)中我们讲到了Activity的测绘流程是如何开始的,接下来我们开始分析UI绘制的三大流程,本文从measure流程开始:在上一篇最后讲到performTraversals方法,该方法内部会分

2021-12-23 18:13:33 1334

原创 Android UI绘制流程分析(二)

源码版本Android 6.0请参阅:http://androidxref.com/6.0.1_r10本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟踪代码逻辑更清晰会省略掉一部分非主干的代码,具体详细代码请翻阅源码。上一篇文章Android UI绘制流程分析(一)Activity.setContentView与DecorView之间的关系我们分析了从Activity启动开始到调用Activity的setContentView方法时DecorView的页面

2021-12-20 01:16:39 1173

原创 Android UI绘制流程分析(一)Activity.setContentView与DecorView之间的关系

源码版本Android 6.0请参阅:http://androidxref.com/6.0.1_r10本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟踪代码逻辑更清晰会省略掉一部分非主干的代码,具体详细代码请翻阅源码。本次不赘述Activity启动流程中的更早时机,对于更早的如何通过binder回调到Activity Thread的这些流程我计划后续再出一篇文章分析,如果不了解可参考这位作者的这篇文章:https://www.jianshu.com/p/6

2021-12-16 23:51:13 1627

原创 Linux进程间通信原理

1.为什么要进行进程间通信Linux系统中内存控件分为:内核空间,用户空间。内核空间中运行系统内核代码以及与硬件密切相关的代码,用户空间中运行用户程序以及与硬件无关部分。应用程序不能直接操控硬件或者调用内核函数,需借助一系列接口函数申请让系统调用相关代码在内核空间运行以获取某些操作硬件或内核程序的能力(也就是系统调用)。例如上层应用在用户空间执行到 open() API函数时,会触发系统软中断,系统调用sys_open(),在内核空间执行open代码,这样用户空间的open函数内部代码就取得了在内核空间

2021-12-05 15:28:30 610

原创 ThreadLocal使用及原理解析

ThreadLocal作用和原理我们知道Java多线程会出现安全问题主要原因是因为多线程同时访问一个共享数据,从而我们解决多线程问题的思路主要有2个:1.给共享数据加锁2.避免多线程操作同一共享数据而思路1是我们平时比较常用的一种方式,但是既然是加锁就必然会有一些性能方面的问题,比如线程等待。所以今天我们讲讲思路2,但是思路2并不能适用于所有线程安全问题,因为在很多具体业务场景下必须让多线程访问同一数据,所以思路2适用于可以将共享数据变为线程私有变量的场景,例如Android中Handler的实现

2021-09-12 23:03:45 674

原创 Java Thread中的join()方法解释

Join作用join是定义在Thread类中的方法,作用是阻塞当前线程的执行,等到被调用join的线程对象执行完毕才执行继续执行当前线程。在Java源码中的定义如下:public final void join() throws InterruptedException { join(0);}public final synchronized void join(long millis) throws InterruptedException接下来我们先来看看join的简单使用,这样能

2021-08-28 00:00:22 7934 1

原创 Java yield方法解释

Thread.yield()用法及解释我们知道在jvm中的并发并非真正的并发,而是cpu将执行过程划分为了时间片,在程序执行过程中,cpu会根据自身的规则分别去调度各个线程。只是这个时间片很短所以给我们的感觉像是并发。某一个线程得到执行也就是这个线程获取到了cpu的执行权。这里再补充一个刚想到的知识点,与yield无关:每个线程内部都有一个程序计数器大体的作用是用于标记当前执行到的代码行数等信息,当某个线程执行过程中cpu执行权被释放的时候,该线程当前执行的相关数据会被存在程序计数器中,等下次该线程重新

2021-08-27 23:59:42 5694

原创 Java Thread中的interrupt()方法的解释

结束线程的思考早前java中线程的结束有2种:1.线程的run()方法执行完毕时,该线程会结束。2.是线程调用stop方法结束。后来java认为在线程中去强制结束其他线程是不安全的,因为被结束的线程可能会有某些必要的操作还来不及执行。当然这个解释只是从网上抄过来的,api中说明的Deprecated原因是说stop将导致它解锁所有已锁定的监视器(这是未检查的ThreadDeath异常向上传播堆栈的自然结果),其实每个对象包含了对象头,实例数据和填充数据,对象头中保存了锁的标志位和指向monito

2021-08-27 23:59:06 2011

原创 Java wait和notify方法解释

wait与notify的API以及解释public final void wait() throws InterruptedException { wait(0);}public final void wait(long timeout, int nanos) throws InterruptedException {}public final native void wait(long timeout) throws InterruptedException;public fina

2021-08-27 23:58:32 460

原创 Java volatile关键字

关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确、完整的理解。很多人遇到需要处理多线程数据竞争问题的时候一律使用synchronized来进行同步,这样在某些场景下其实很影响性能。所以了解volatile其实很有必要。当一个变量被定义为volatile之后,它将具备两种特性:1.保证此变量对所有线程的可见性。这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的,而普通变量就做不到这一点。2.在对此变量的读写操作上是禁止指令

2021-08-27 23:56:32 99

原创 Activity四种启动模式图解

Android中,每个Activity都需要从属于一个Task,这个Task是Android相对于Activity的一个概念,Task是一组相关联的Activity的集合,它存在于一个叫back stack的数据结构中,而framework层调度Activity都是通过管理这个back stack的数据结构来完成的,所以可以就理解为framework层是通过任务栈的形式来管理调度Activity的...

2019-06-01 19:38:11 268

原创 Android中Activity启动过程源码阅读笔记:

Android中Activity启动过程探究:    本篇笔记主要从视图的角度来探究启动过程,关于线程,Application等操作较为复杂待有空再研究。    首先,Android的语法就是java语言,而一个java项目的入口是public static void main(String[] args),在Android项目中,如果也是同理:ActivityThread类中的public ...

2019-04-17 11:36:03 136

原创 简单的讲讲Java的线程的复用

我们都知道Java现在提供了很多线程池,我们可以通过线程池的 execute(Runnable run)方法轻松的复用线程,也用不着管这个线程是怎么被复用的。今天我突然想到一个问题,Java中的线程都是Thread,而Thread也没有提供说让我们可以同一个线程执行多个Runnable的方法,那线程是怎么复用的呢?线程池原理其实线程池的实现无非就是两点,一个任务队列,一个就是复用线程。队列:...

2019-01-21 17:07:02 1598

原创 设计模式-代理模式

java的代理模式是很常见的一种设计模式,记录一下我的理解。代理模式主要的思想是将委托类(被代理类)和真正使用委托类逻辑的类做一个解耦。太官方的原理我也说不好,所以还是说说自己的理解好了。java的代理模式分两种:静态代理动态代理我个人认为,如果要理解这种思想,还是主要要搞懂静态代理,这样才能更好地理解这种模式,而动态代理则是调用java的Proxy这个API对静态代理做的一种更...

2018-12-12 14:49:58 208

原创 Android中多线程通信:Handler的理解

Android中的HandlerAndroid中Handler在我理解主要是为了解决线程间通信。使用Android的Handler机制主要要了解几个类:Looper:一个线程对应一个或者0个Looper,主线程在ActivityThread的时候会默认创建一个Looper,非主线程中需要先通过Looper.prepare()创建,并且通过Looper.loop()开启。Message:...

2018-12-09 23:00:41 750

空空如也

空空如也

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

TA关注的人

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