Android日常学习记录
文章平均质量分 87
lianwenhong
一个程序员
展开
-
Jetpack-LiveData原理补充
当Fragment2点击返回回到Fragment1时Fragment1又执行了onCreateView()生命周期,这样在onCreateView()到onDestroyView()之间执行的LiveData数据观察者绑定又被执行了一次,此时又由于每次observe时绑定的Observer对象都不是同一个就会导致同一个LiveData其实是被重复绑定了数据观察者。而Fragment则是在performDestroy()方法中也就是onDestroyView()之后onDestroy()之前才执行。原创 2022-09-16 18:11:37 · 560 阅读 · 1 评论 -
Jetpack-LiveData
LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如activity、fragment或service)的生命周期。这种感知能力可确保LiveData仅更新处于活跃生命周期状态的应用组件观察者。如果观察者(由 Observer类表示)的生命周期处于STARTED或RESUMED状态,则LiveData会认为该观察者处于活跃状态。LiveData只会将更新通知给活跃的观察者。原创 2022-09-16 18:06:25 · 788 阅读 · 0 评论 -
Jetpack-ViewModel
ViewModel是Android Jetpack库中的一员,旨在以注重生命周期的方式存储和管理界面相关的数据。其与生命周期强相关。在组件(Activity/Fragment)的生命周期中ViewModel的数据会一直保存在内存中,即便在组件发生重建时(例如当Activity屏幕旋转或者设置改变等原因导致的页面重建)也会一直存在。ViewModel可以实现组件之间的数据共享,主要是通过使用相同的ViewModelStore来进行共享。原创 2022-09-06 15:13:41 · 840 阅读 · 0 评论 -
Jetpack-Lifecycle
lifecycle的设计其实非常简单,就是一个典型的观察者模式。假设让我们用自己的思路实现一个最简单的监测Activity生命周期的观察者,动手之前思考一下观察者模式必备的几个角色:**1.被观察者**,**2.观察者**,**3.调度类(管理观察者和被观察者之间关系)**。原创 2022-08-23 15:54:36 · 640 阅读 · 0 评论 -
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 · 683 阅读 · 0 评论 -
Android小知识-HandlerThread
如果你在开发android项目时想实现一个带消息队列的子线程,那我建议你不要重复造轮子,你可以看看HandlerThread这个类,它就是系统封装好的一个很好用的带消息队列的子线程。其实HandlerThread只是系统对子线程开发需求的一个小封装而已,但是我个人觉得挺实用的。上面代码中的注释已经很详细的说明了HandlerThread的原理,结合它的使用方式看源码应该是一目了然了。Android线程间通信主要方式是使用Handler相信没有一个做Android的人不知道。...原创 2022-07-26 17:10:25 · 549 阅读 · 0 评论 -
binder(三)binder简介
前文binder(一)Linux必备知识篇已经了解过一些Linux相关的知识。因为Android是基于Linux内核的操作系统,所以Android也具备Linux进程隔离的特性。每个进程都是一块单独的内存单元,各个进程之间要互相通信需要一套IPC机制来实现。简单介绍一下Linux进程间通信方式。linux中主要的进程通信包括以下几种:以上是Linux进程间通信的几种主要方式,各种方式都有自己的优缺点,也有自己的擅长使用领域,可自行了解一下。在Android中主要是采用Binder来实现的。当然并不是说An原创 2022-07-04 15:30:20 · 314 阅读 · 0 评论 -
Android序列化之Parcel
Android操作系统的底层数据传输形式是简单的字节序列形式进行传递。用通俗的话说就是系统不认识对象,只认识字节序列。而我们为了达到通信或者存储的目的,需要先将数据序列化传递,要使用时再进行反序列化还原。我们知道Android系统是基于Linux系统实现的,而Linux有进程隔离的机制。而进程如果传递复杂数据类型那传递的是对象的引用,本质上就是一个内存地址。但是传递内存地址的方式在跨进程中明显不行,由于Linux采用了虚拟内存机制,两个进程都有自己独立的内存地址空间,所以把A进程中某个对象的内存地址传递给B原创 2022-06-27 16:44:41 · 2773 阅读 · 0 评论 -
最讨厌QA提按钮快速点击的bug了
首先声明:本库的编写是被QA逼出来的。在开发过程中经常被QA提一类恶心的bug(快速点击控件出现多个页面或多个弹窗等)我司QA拿到包之后第一件事就爱测快速点击的场景,他们认为同一个按钮快速点击可能是误操作不应该得到响应。比如某个按钮点击之后应该弹出一个dialog,QA双击控件就出现2个dialog。这原本应该是个正常的场景,但是奈何抵不过他们一直提,所以就做了这个小功能加以限制。其实这就是个典型的AOP编程了。屏蔽快速点击最常见的操作是做一个工具类:这样就能解决90%问题。奈何我司QA测得又比较细,某天原创 2022-06-23 19:45:37 · 621 阅读 · 0 评论 -
binder(三)mmap浅析(转载记录)
前言介绍 mmap 的文章很多,本文主要结合官方文档、之前看到的一些比较不错的文章进行一个总结。概念在计算机中,mmap 是 POSIX(Portable Operating System Interface of UNIX 可移植 UNIX 操作系统接口,制定了标准 API 接口规范) 兼容的 Unix 系统调用,可以将文件或设备映射到内存中,这是一种内存映射文件 I/O 的方法。实现了按需加载分页,不直接从磁盘读取文件内容,并且初始化时根本不使用物理 RAM。在访问特定位置后,以 lazy 方式从原创 2022-05-03 21:42:54 · 354 阅读 · 0 评论 -
binder(二)MMU浅析
什么是虚拟内存在现代的操作系统中,当你对内存地址进行操作时其实操作的并不是物理内存地址,而是系统虚拟出来的一个虚拟内存地址。通过简单的图例说明虚拟内存的概念。操作系统的物理内存是固定的,我们这里指的是RAM。当操作系统运行多个进程时,每个进程如果直接访问物理内存,那是不是就会出现你进程P1访问地址A时如果进程P2也访问该地址,那就会造成进程之间的冲突。所以当代操作系统引入了虚拟内存的概念。在创建P1和P2进程时,操作系统会分别告诉它们我整个内存都是你的,可是事实上操作系统给它们画了大饼,其实它们得原创 2022-05-03 21:30:06 · 1301 阅读 · 0 评论 -
binder(一)Linux必备知识篇
对linux操作系统中某些概念做简单预习,旨在为后续Android学习提供前提铺垫。例如学习binder、锁机制等等。软件程序管理Linux操作系统将运行中的程序成为进程。而Linux内核控制这Linux操作系统如何管理运行在系统上的所有进程。内核创建了第一个进程(init进程)来启动系统上所有其他进程。 当内核启动时,他会将init进程加载到虚拟内存中。内核在启动任何进程时都会在虚拟内存中为该进程分配一块专有区域用于存储该进程用到的数据和代码。进程隔离Linux中为每一个进程分配内存时都将内存原创 2022-04-21 18:47:31 · 2922 阅读 · 0 评论 -
装饰者设计模式
简述装饰者模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),以透明动态的方式来动态扩展对象的功能,也是继承关系的一种代替方案。Component:抽象组件(可以是抽象类或者接口),被装饰的原始对象ConcreteComponent:具体实现类,被装饰的具体对象Decorator:抽象装饰者,职责就是为了装饰我们的组件对象,内部一定要有一个指向组件对象的引用ConcreteDecoratorA:装饰者具体实现类,只对抽象装饰者做出具体实现Concret原创 2022-04-15 15:34:30 · 63 阅读 · 0 评论 -
Java泛型
泛型也叫“参数化类型”,是在java1.5之后才有的用法之所以出现泛型的最主要原因是能提高java程序的类型安全,使得当程序的类型转换错误能在提早得到暴露(将类型错误从运行时暴露提前到编译时)。假设不使用泛型,那么创建例如ArrayList这种容器类时如果想让该容器支持存储各种类型的数据则需要将ArrayList所能存储的数据定义为Object。假设存入时同一个容器存入了不同的数据类型,那么使用时很可能因为失误造成低级错误:public void test(){ ArrayList<O原创 2022-03-21 23:22:12 · 2603 阅读 · 0 评论 -
动态插桩技术以及动态类加载
运行时机原理图:class文件简介Java编译器编译好Java文件之后,产生.class 文件在磁盘中。这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码。JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象:class字节码文件是根据JVM虚拟机规范中规定的字节码组织规则生成的、具体class文件是怎样组织类信息的,可以参考 此博文:深入理解Java Class文件格式系列。或者是Java虚拟机规范。在运行期的原创 2022-03-21 16:45:32 · 432 阅读 · 0 评论 -
java锁机制 偏向锁-轻量级锁-重量级锁
首先粗略了解一下java对象的内存结构:紧接着看下Mark Word的内存结构(以下都用缩写MW代表Mark Word):再看下当一个对象被当成锁对象之后的内存结构变化:当对象处于无锁状态时没什么好说的,它并没有多线程的情况。当对象处于多线程环境下,我们往往是通过给对象加锁的做法来保证多线程操作共享变量的安全性,此时为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一。本文主要了解一个对象在多线程环境下的锁膨胀机制,大概就是无锁->偏向锁->轻量锁->重原创 2022-01-11 10:44:59 · 733 阅读 · 1 评论 -
Java锁机制之synchronized
java中2种锁的实现原理区别:synchronized: 在软件层面依赖JVM,在jvm将class文件编译成字节码文件时添加monitorenter和monitorexit句柄来区分加锁代码块Lock: 在硬件层面依赖特殊的CPU指令。synchronized机制:首先需要明确的一点是:Java多线程的锁都是基于对象的,Java中的每一个非空对象都可以作为一个锁。synchronized关键字锁具体表现为:锁对象和锁对象的class类;每个类可以有很多实例对象,不同实例对象的对象锁互不干扰,但原创 2022-01-08 22:26:05 · 3443 阅读 · 1 评论 -
Android23-app启动流程
源码版本Android 6.0请参阅:http://androidxref.com/6.0.1_r10本文目的是分析从Activity启动到走完绘制流程并显示在界面上的过程,在源码展示阶段为了使跟踪代码逻辑更清晰会省略掉一部分非主干的代码,具体详细代码请翻阅源码。暂时只上传分析之后的流程图,具体细节等有时间再写。本流程图表述了一个App从启动开始到执行Activity的onCreate()方法为止。...原创 2022-01-04 16:03:44 · 1074 阅读 · 0 评论 -
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 · 90 阅读 · 0 评论 -
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 · 1343 阅读 · 0 评论 -
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 · 1183 阅读 · 0 评论 -
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 · 1645 阅读 · 0 评论 -
Linux进程间通信原理
1.为什么要进行进程间通信Linux系统中内存控件分为:内核空间,用户空间。内核空间中运行系统内核代码以及与硬件密切相关的代码,用户空间中运行用户程序以及与硬件无关部分。应用程序不能直接操控硬件或者调用内核函数,需借助一系列接口函数申请让系统调用相关代码在内核空间运行以获取某些操作硬件或内核程序的能力(也就是系统调用)。例如上层应用在用户空间执行到 open() API函数时,会触发系统软中断,系统调用sys_open(),在内核空间执行open代码,这样用户空间的open函数内部代码就取得了在内核空间原创 2021-12-05 15:28:30 · 619 阅读 · 0 评论 -
Activity四种启动模式图解
Android中,每个Activity都需要从属于一个Task,这个Task是Android相对于Activity的一个概念,Task是一组相关联的Activity的集合,它存在于一个叫back stack的数据结构中,而framework层调度Activity都是通过管理这个back stack的数据结构来完成的,所以可以就理解为framework层是通过任务栈的形式来管理调度Activity的...原创 2019-06-01 19:38:11 · 291 阅读 · 0 评论 -
Android中Activity启动过程源码阅读笔记:
Android中Activity启动过程探究: 本篇笔记主要从视图的角度来探究启动过程,关于线程,Application等操作较为复杂待有空再研究。 首先,Android的语法就是java语言,而一个java项目的入口是public static void main(String[] args),在Android项目中,如果也是同理:ActivityThread类中的public ...原创 2019-04-17 11:36:03 · 157 阅读 · 0 评论 -
简单的讲讲Java的线程的复用
我们都知道Java现在提供了很多线程池,我们可以通过线程池的 execute(Runnable run)方法轻松的复用线程,也用不着管这个线程是怎么被复用的。今天我突然想到一个问题,Java中的线程都是Thread,而Thread也没有提供说让我们可以同一个线程执行多个Runnable的方法,那线程是怎么复用的呢?线程池原理其实线程池的实现无非就是两点,一个任务队列,一个就是复用线程。队列:...原创 2019-01-21 17:07:02 · 1635 阅读 · 0 评论 -
Android中多线程通信:Handler的理解
Android中的HandlerAndroid中Handler在我理解主要是为了解决线程间通信。使用Android的Handler机制主要要了解几个类:Looper:一个线程对应一个或者0个Looper,主线程在ActivityThread的时候会默认创建一个Looper,非主线程中需要先通过Looper.prepare()创建,并且通过Looper.loop()开启。Message:...原创 2018-12-09 23:00:41 · 762 阅读 · 0 评论