Android事件分发机制二:viewGroup与view对事件的处理
前言很高兴遇见你~
在上一篇文章 Android事件分发机制一:事件是如何到达activity的? 中,我们讨论了触摸信息从屏幕产生到发送给具体 的view处理的整体流程,这里先来简单回顾一下:
触摸信息从手机触摸屏幕时产生,通过IMS和WMS发送到viewRootImpl
viewRootImpl把触摸信息传递给他所管理的view
view根据自身的逻辑对事件进行分发
常见的如Activity布局的顶层viewGroup为DecorView,他对事件分发方法进行了重新,会优先回调windowCallBack也就是Activity的分发方法
最后事件都会交给viewGroup去分发给子view
前面的分发步骤我们清楚了,那么viewGroup是如何对触摸事件进行分发的呢?View又是如何处理触摸信息的呢?正是本文要讨论的内容。
事件处理中涉及到的关键方法就是 dispatchTouchEvent ,不管是viewGroup还是view。在viewGroup中,dispatchTouchEvent 方法主要是把事件分发给子view,而在view中,dispatchTouchEven ...
Android事件分发机制一:事件是如何到达activity的?
事件分发,真的一定从Activity开始吗?
前言很高兴遇见你~
事件分发,android中一个老生常谈的话题了。前阵子去面试一家企业,他里面有一道笔试题问到事件分发的流程,正确答案是选择:Activity->window->view,基本的流程我们也都知道是从Activity开始分发。
当时我选择完之后,我就开始思考,那事件是怎么到达Activity的?如果了解过window机制的读者会知道,事件分发也是window机制的一部分,而Activity不属于window机制内,那么触摸事件应该是从Window开始才对,怎么是从Activity开始的呢?
抱着这些疑问,我重新学习了事件分发,结合之前的window机制内容,对于事件分发的理解又有了新的认知。这篇文章就是要回答事件是如何到达Activity的这个问题。
你以为我接下来要开始讲源码、系统底层了?不不不,本文不讲这些。我们要探究的是,一个触摸信息从系统底层产生之后,一步步到达Activity进行分发的整体流程。而关于系统底层的逻辑,不在本文的讨论范围内。
本文是笔者android触摸事件系列文章的开篇,主要的内容是 ...
Java之String重点解析
String s = new String("abc")这段代码创建了几个对象呢?s=="abc"这个判断的结果是什么?s.substring(0,2).intern()=="ab"这个的结果是什么呢?
s.charAt(index) 真的能表示出所有对应的字符吗?
"abc"+"gbn"+s直接的字符串拼接是否真的比使用StringBuilder的性能低?
前言很高兴遇见你~
Java中的String对象特性,与c/c++语言是很不同的,重点在于其不可变性。那么为了服务字符串不可变性的设计,则衍生出非常多的相关问题:为什么要保持其不可变?底层如何存储字符串?如何进行字符串操作才拥有更好的性能?等等。此外,字符编码的相关知识也是非常重要;毕竟,现在使用emoij是再正常不过的事情了。
文章的内容围绕着不可变 这个重点展开:
分析String对象的不可变性;
常量池的存储原理以及intern方法的原理
字符串拼接的原理以及优化
代码单元与代码点的区别
总结
那么,我们开始吧~
...
HashMap相关类:Hashtable、LinkHashMap、TreeMap
前言很高兴遇见你~
在 深入剖析HashMap 文章中我从散列表的角度解析了HashMap,在 深入解析ConcurrentHashMap:感受并发编程智慧 解析了ConcurrentHashMap的底层实现原理。本文是HashMap系列文章的第三篇,主要内容是讲解与HashMap相关的集合类。
HashMap本身功能已经相对完善,但在某些特殊的情景下,他就显得无能为力,如高并发、需要记住key插入顺序、给key排序等。实现这些功能往往需要付出一定的代价,在没有必然的需求情景下,增添这些功能是没必要的。因而,为了提高性能,Java并没有把这些特性直接集成到HashMap中,拓展了拥有这些特性的其他集合类作为补充:
线程安全的ConcurrentHashMap、Hashtable、SynchronizeMap
记住插入顺序的LinkedHashMap
记录key顺序的TreeMap
这样,我们就可以在特定的需求情景下,选择最适合我们的集合框架,从而来提高性能。那么今天这篇文章,主要就是分析这些其他的集合类的特性以及底层原理,重点分析与HashMap的区别。关于ConcurrentHa ...
深入解析ConcurrentHashMap:感受并发编程智慧
如果有一个整型变量count,多个线程并发让count自增1,你会怎么设计?
你知道如何让多个线程协作完成一件事件吗?
前言很高兴遇见你~
ConcurrentHashMap是个老生常谈的集合类了,我们都知道多线程环境下不能直接使用HashMap,而需要使用ConcurrentHashMap,但有没有了解过ConcurrentHashMap到底是如何实现线程安全的呢?他到底跟传统的Hashtable和SynchronizeMap(没听过SynchronizeMap?他就是Collections.synchronizeMap方法返回的对象)到底好在哪?
ConcurrentHashMap建立在HashMap的基础上实现了线程安全,关于HashMap读者可以参考这篇文章:深入剖析HashMap,从散列表的三大要素:哈希函数、哈希冲突、扩容方案、以及线程安全展开详解HashMap的设计。关于HashMap的内容本文不再赘述,读者若对HashMap的底层设计不了解,一定要先去阅读前面的文章。ConcurrentHashMap中蕴含的并发编程智慧是非常值得我们学习的,正如文章开头的两个问 ...
深入解析HashMap
前言很高兴遇见你~
HashMap是一个非常重要的集合,日常使用也非常的频繁,同时也是面试重点。本文并不打算讲解基础的使用api,而是深入HashMap的底层,讲解关于HashMap的重点知识。需要读者对散列表和HashMap有一定的认识。
HashMap本质上是一个散列表,那么就离不开散列表的三大问题:散列函数、哈希冲突、扩容方案;同时作为一个数据结构,必须考虑多线程并发访问的问题,也就是线程安全。这四大重点则为学习HashMap的重点,也是HashMap设计的重点。
HashMap属于Map集合体系的一部分,同时继承了Serializable接口可以被序列化,继承了Cloneable接口可以被复制。他的的继承结构如下:
HashMap并不是全能的,对于一些特殊的情景下的需求官方拓展了一些其他的类来满足,如线程安全的ConcurrentHashMap、记录插入顺序的LinkHashMap、给key排序的TreeMap等。
文章内容主要讲解四大重点:散列函数、哈希冲突、扩容方案、线程安全,再补充关键的源码分析和相关的问题。
本文所有内容如若未特殊说明,均为JDK1.8版本。
哈希 ...
Android全面解析之Activity生命周期
前言很高兴遇见你~ 欢迎阅读我的文章。
关于Activity生命周期的文章,网络上真的很多,有很多的博客也都讲得相当不错,可见Activity的重要性是非常高的。事实上,我猜测每个android开发者接触的第一个android组件都是Activity。我们从新建第一个Activity开始,运行了代码,看到模拟机上显示了一个MainActivity标题和一行HolleWorld,从此打开Android世界的大门。
本篇文章讲解的重点是Activity的生命周期,在文章的最后也会涉及Activity的设计。不同于其他的博客设计,文章采用系统化的讲解,关于Activity生命周期的相关知识基本都会涉及到。
文章第一部分讲解关于Activity状态的认知;
第二部分全面讲解activity生命周期回调方法;
第三部分是分析不同情景下的生命周期回调顺序:
第四部分是原码分析;
最后一部分是从更高的角度来思考activity以及生命周期。
那么,我们开始吧。
生命状态概述Activity是一个很重要、很复杂的组件,他的启动不像我们平时直接new一个对象就完事了,他需要经历一系列的初始化。例如” ...
深入解析volatile关键字
前言很高兴遇见你~ 欢迎阅读我的文章。
volatile关键字在Java多线程编程编程中起的作用是很大的,合理使用可以减少很多的线程安全问题。但其实可以发现使用这个关键字的开发者其实很少,包括我自己。遇到同步问题,首先想到的一定是加锁,也就是synchronize关键字,暴力锁解决一切多线程疑难杂症。但,锁的代价是很高的。线程阻塞、系统线程调度这些问题,都会造成很严重的性能影响。如果在一些合适的场景,使用volatile,既保证了线程安全,又极大地提高了性能。
那为啥放着好用的volatile不用,偏偏要加锁呢?一个很重要的原因是:不了解什么是volatile。加锁简单粗暴,几乎每个开发者都会用(但不一定可以正确地用),而volatile,可能压根就不知道有这个东西(包括之前的笔者=_=)。那volatile是什么东西?他有什么作用?在什么场景下适用?他的底层原理是什么?他真的可以保证线程安全吗?这一系列问题,是面试常见相关题目,也正是这篇文章要啊解决的问题。
那么,我们开始吧。
认识volatilevolatile关键字的作用有两个:变量修改对其他线程立即可见、禁止指令重排。
第二个 ...
JVM基础(三):垃圾回收机制
前言很高兴遇见你~ 欢迎阅读我的文章。
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来
垃圾收集(Garbage Collection ,也称为GC),是虚拟机中一个永恒不变的话题。上述那句话堪称经典,同时也点出了垃圾回收这个问题的重要性。在c/c++中,开发者对内存有至高无上的权利,同时也需要自己对对象负责到底,每一块内存使用完之后都需要调用free方法来释放内存。而JVM采用自动化技术,开发者无需关心内存的分配以及释放,当一个对象不再使用时,垃圾回收机制会这个对象进行回收。然而,这一切看起来很美好的垃圾回收机制,背后却“暗藏杀机”。垃圾回收机制并不是完美的,若开发不当很容易产生内存泄露的内存溢出等问题;同时当内存泄漏或内存溢出问题时,如果对JVM的垃圾回收机制不了解,也很难去排查问题。因而,学习垃圾回收机制不仅是需要应付面试,更重要的是能够让自己写出更加健壮的代码、解决垃圾回收机制带来的问题。
垃圾回收机制有四个关键问题:
什么是垃圾回收机制?
回收哪个区域的垃圾?
什么时候回收?
如何回收?
这四个问题可以说是 ...
JVM基础(二):运行时数据区
前言很高兴遇见你~ 欢迎阅读我的文章。
在上一篇文章JVM基础(一):认识虚拟机中,介绍了什么是虚拟机,以及字节码class文件。这一篇文章主要讲关于JVM的运行时数据区结构。
我们知道,c/c++在内存上划分为了栈和堆区,栈区存放函数的局部变量等,堆区为用户自主开辟的空间。当开发者需要新建一个对象时,首先需要在堆区中开辟一个空间,再初始化,使用。最后需要自己手动去释放该内存区域。而JVM把这些工作都做好了,当我们需要新建一个对象的时候,只需要一个关键字new即可创建一个对象,当我们不再使用这个对象的时候,垃圾回收机制会帮我们自动回收该内存。两种方式各有优势,c/c++对内存有至高无上的权利,同时也意味着自己有更重的责任去管理对象的生命周期;JVM自动管理内存,向开发者屏蔽了直接的内存操作,但是如果对JVM的运行时数据区认识不够,就很容易发生内存泄露、内存溢出等问题。这也是我们需要学习JVM运行时数据区的原因之一。
JVM运行时数据区结构和c/c++有点相似,同样分配了栈区与堆区。具体的结构如下图:
我们的class文件通过类加载系统,被加载到虚拟机中,在虚拟机进行处理。执行引擎负 ...
JVM基础(一):认识虚拟机
前言很高兴遇见你~ 欢迎阅读我的文章。
JVM是每个Java程序员必须迈过去的一个坎,因为它实在是太重要了。Java的底层知识,归根结底,都是JVM相关知识。很多读者看到jvm就感觉:哦这是底层知识,算了先学好应用层再说。或者到了面试需要不得不背诵几道题。在我看来,了解JVM是理解整个Java生态的必经之路。编程语言的发展,从机器码01串到现在的高级Java语言,这里面凝结了无数先驱的智慧。了解JVM,不只是为了面试,更是为了感受前人的智慧,学习JVM也可以让我们的Java程序更加地健壮。
而关于非JVM研究人员来说,可能我们并需要很深入去研究,理解他的概念模型就已经满足了。作为一个Android工程师,JVM也是必学的内容之一。JVM基础系列文章,主要讲述关于JVM需要了解的关键基础知识,不会去深入研究JVM的底层知识。对于一个Android工程师,这些肯定是足够的了,对JVM有兴趣的读者,可以看完之后继续深入去研究,相信这一系列文章也可以很好地给你提供一个学习JVM的指引。
第一篇我们来聊聊JVM。为什么说JVM是人类在编程语言上迈出的一大步?JVM在整个Java程序运行中扮演了什 ...
Android之window机制token验证
前言很高兴遇见你~ 欢迎阅读我的文章
这篇文章讲解关于window token的问题,同时也是Context机制和Window机制这两篇文章的一个补充。如果你对Android的Window机制和Context机制目前位了解过,强烈建议你先阅读前面两篇文章,可以帮助理解整个源码的解析过程以及对token的理解。同时文章涉及到Activty启动流程源码,读者可先阅读Activity启动流程这篇文章。文章涉及到这些方面的内容默认读者已经阅读且了解,不会对这方面的内容过多阐述,如果遇到一些内容不理解,可以找到对应的文章看一下。那么,我们开始吧。
当我们想要在屏幕上展示一个Dialog的时候,我们可能会在Activity的onCreate方法里这么写:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dialog = AlertDialog.Builder(th ...