Android 高工面试必考题(二),带你碾压面试官

注意截图中,我增加了一些注释,便于我们更加方便的理解,由于我们一般产生点击事件都是 MotionEvent.ACTION_DOWN,所以一般都会调用到 onUserInteraction() 这个方法。我们不妨来看看都做了什么。

很遗憾,这个方法实现是空的,不过我们可以从注释和其他途径可以了解到,该方法主要的作用是实现屏保功能,并且当此 Activity 在栈顶的时候,触屏点击 Home、Back、Recent 键等都会触发这个方法。

再来看看第二个 if 语句,getWindow().superDispatchTouchEvent()getWindow() 明显是获取 Window,由于 Window 是一个抽象类,所以我们能拿到其子类 PhoneWindow,我们直接看看 PhoneWindows.superDispatchTouchEvent() 到底做了什么操作。

直接调用了 DecorView 的 superDispatchTrackballEvent() 方法。DecorView 继承于 FrameLayout,作为顶层 View,是所有界面的父类。而 FrameLayout 作为 ViewGroup 的子类,所以直接调用了 ViewGroup 的 dispatchTouchEvent()

ViewGroup 的事件分发机制

我们通过查看 ViewGroup 的 dispatchTouchEvent() 可以发现。

注意其中红框里面的代码,看注释也能知道,定义了一个 boolean

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

值变量 intercept 来表示是否要拦截事件。

其中采用到了 onInterceptTouchEvent(ev) 对 intercept 进行赋值。大多数情况下,onInterceptTouchEvent() 返回值为 false,但我们完全可以通过重写 onInterceptTouchEvent(ev) 来改变它的返回值,不妨继续往下看,我们后面对这个 intercept 做了什么处理。

暂时忽略 判断的 canceled,该值同样大多数时候都返回 false,所以当我们没有重写 onInterceptTouchEvent() 并使它的返回值为 true 时,一般情况下都是可以进入到该方法的。

继续阅读源码可以发现,里面做了一个 For 循环,通过倒序遍历 ViewGroup 下面的所有子 View,然后一个一个判断点击位置是否是该子 View 的布局区域,当然还有一些其他的,由于篇幅原因,这里就不细讲了。

View 的事件分发机制

ViewGroup 说到底还是一个 View,所以我们不得不继续看看 View 的 dispatchTouchEvent()

截图中的代码是有删减的,我们重点看看没有删减的代码。

红框中的三个条件,第一个我就不用说了。

  • (mViewFlags & ENABLED_MASK) == ENABLED

该条件是判断当前点击的控件是否为 enable,但由于基本 View 都是 enable 的,所以这个条件基本都返回 true。

  • mOnTouchListener.onTouch(this, event)

即我们调用 setOnTouchListener() 时必须覆盖的方法 onTouch() 的返回值。

从上述的分析,终于知道「onTouch() 方法优先级高于 onTouchEvent(event) 方法」是怎么来的了吧。

再来看看 onTouchEvent()

从上面的代码可以明显地看到,只要 View 的 CLICKABLE 和 LONG_CLICKABLE 有一个为 true,那么 onTouchEvent() 就会返回 true 消耗这个事件。CLICKABLE 和 LONG_CLICKABLE 代表 View 可以被点击和长按点击,我们通常都会采用 setOnClickListener() 和 setOnLongClickListener() 做设置。接着在 ACTION_UP 事件中会调用 performClick() 方法,我们看看都做了什么。

从截图中可以看到,如果 mOnClickListener 不为空,那么它的 onClick() 方法就会调用。

总结

本来写到这就结束了,但回顾一遍还是打算给大家稍微总结一下。

需要总结的小点:

1、Android 事件分发总是遵循 Activity => ViewGroup => View 的传递顺序;

2、onTouch() 执行总优先于 onClick()

原本想用文字总结的,结果发现简书上还有这样一篇神文:Android事件分发机制详解:史上最全面、最易懂,所以直接引用一下其中的图片。

  • Activity 的事件分发示意图

  • ViewGroup 事件分发示意图

  • View 的事件分发示意图

  • 事件分发工作流程总结

最后分享一波面试复习路线

多余的话就不讲了,接下来将分享面试的一个复习路线,如果你也在准备面试但是不知道怎么高效复习,可以参考一下我的复习路线,有任何问题也欢迎一起互相交流,加油吧!

这里给大家提供一个方向,进行体系化的学习:

1、看视频进行系统学习

前几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时。

另外,我自己也珍藏了好几套视频,有需要的我也可以分享给你。

2、进行系统梳理知识,提升储备

客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

系统学习方向:

  • **架构师筑基必备技能:**深入Java泛型+注解深入浅出+并发编程+数据传输与序列化+Java虚拟机原理+反射与类加载+动态代理+高效IO

  • **Android高级UI与FrameWork源码:**高级UI晋升+Framework内核解析+Android组件内核+数据持久化

  • **360°全方面性能调优:**设计思想与代码质量优化+程序性能优化+开发效率优化

  • **解读开源框架设计思想:**热修复设计+插件化框架解读+组件化框架设计+图片加载框架+网络访问框架设计+RXJava响应式编程框架设计+IOC架构设计+Android架构组件Jetpack

  • **NDK模块开发:**NDK基础知识体系+底层图片处理+音视频开发

  • **微信小程序:**小程序介绍+UI开发+API操作+微信对接

  • **Hybrid 开发与Flutter:**Html5项目实战+Flutter进阶

知识梳理完之后,就需要进行查漏补缺,所以针对这些知识点,我手头上也准备了不少的电子书和笔记,这些笔记将各个知识点进行了完美的总结。

3、读源码,看实战笔记,学习大神思路

“编程语言是程序员的表达的方式,而架构是程序员对世界的认知”。所以,程序员要想快速认知并学习架构,读源码是必不可少的。阅读源码,是解决问题 + 理解事物,更重要的:看到源码背后的想法;程序员说:读万行源码,行万种实践。

主要内含微信 MMKV 源码、AsyncTask 源码、Volley 源码、Retrofit源码、OkHttp 源码等等。

4、面试前夕,刷题冲刺

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值