越来越多的人在提“移动端的下半场”、“AndroID 开发的焦虑”之类的,也有人在喊“技术天天在变,学也学不完”,“昨天 Kotlin 今天 Flutter”。其实我却认为,如果你技术达到了一定程度,你无需太过在意这些。
移动端真正进入下半场了吗?于我看来并没有,最多说“AndroID 技术的探索”进入了下半场,而整个市场还是乐观的。以前是 BAT 的天下,而近两年出来越来越多的独角兽:头条、抖音、拼多多、快手、小猿搜题等,这些公司的业务都在移动端上,他们需要招聘更多的移动端人才。如果真要说下半场,只能说很多小型创业公司在退出市场,这确实会导致很多入门工程师失业,但这也说明了这个行业在更加规范。
而且,对于 AndroID 工程师而言,这更是个好的时代。互联网下沉,那么下沉市场里的用户是使用 AndroID 多还是 iOS 多,大家都清楚。
那么,对于工程师而言需要做什么才能存活呢?很简单,要么转行,要么提高。我相信,一个技术不错的工程师,不但无需焦虑,而且在这个时代,能够拥有稳定的职业生涯和丰厚的收入。
面试官:说说vIEw中的事件分发?androID中事件分发机制是androID中常见的问题,一般大家都知道vIEw的分发事件是从vIEw的VIEwgroup(Parent)#dispatchtouchEvent
到VIEwgroup(Parent)#onIntercepttouchEvent
再到VIEw#dispatchtouchEvent
,然后到vIEw的ontouchEvent
,最后又回到了VIEwgroup(Parent)#ontouchEvent
。如果大家记不住方法名,可以直接说先是parent的分发到拦截再到vIEw的分发,再到vIEw的消费,最后到parent的消费
这样回答肯定是很浅显的,因为没有说出是否拦截、是否分发、是否消费的各种条件,没有涉及到各种action的分发情况,上面说的默认分发只是针对action_down的,因为vIEw/vIEwgroup
各种super调用都是不进行分发、拦截、消费的,所以在没找到处理touch事件的vIEw时候,是一直往上层vIEw传递的,一直传到activity里面,下面我们再来整理一下:
如果vIEwgroup不进行分发,那么
action_down
、action_move
和action_up
只会执行到vIEwgroup的dispatchtouchEvent
,不分发的条件是dispatchtouchEvent
直接返回true或false,true和false的区别是true会执行action_down
、action_move
和action_up
,而如果直接返回false只会执行到action_down。并且后续的vIEwgroup的onIntercepttouchEvent
后续方法都不会被执行到。
关于为什么vIEw/VIEwgroup的dispatchtouchEvent
返回true的时候三个action都能执行到,而返回false的话,只能执行到action_down,这个需要到vIEw/VIEwgroup的父类中dispatchtouchEvent
找答案,该方法中会在action_down的时候调用dispatchtransformedtouchEvent
方法,而该方法是通过子vIEw的dispatchtouchEvent方法的返回值来决定父类的dispatchtransformedtouchEvent
方法的返回值,而dispatchtransformedtouchEvent
的返回值会决定mFirsttouchTarget
是否为空,所以在action_down的过程中实际中通过子vIEw的dispatchtouchEvent
方法返回值来确定mFirsttouchTarget
是否为空。这里贴出vIEwgroup中dispatchtransformedtouchEvent
方法的删减代码:
private boolean dispatchtransformedtouchEvent(MotionEvent event, boolean cancel, VIEw child, int desiredPointerIDBits) { ------------------ //省略了cancel部分的代码 ------------------------ //如果child为空,直接调用自己的dispatchtouchEvent方法,此时自己就相当于一个vIEw,touch事件走自己的 if (child == null) { handled = super.dispatchtouchEvent(transformedEvent); } else { final float offsetX = mScrollX - child.mleft; final float offsetY = mScrollY - child.mtop; transformedEvent.offsetLocation(offsetX, offsetY); if (! child.hasIDentityMatrix()) { transformedEvent.transform(child.getInverseMatrix()); } //返回值直接通过孩子来获取返回值 handled = child.dispatchtouchEvent(transformedEvent); } transformedEvent.recycle(); return handled;}
所以如果vIEw/vIEwgroup的dispatchtouchEvent
方法返回false,表示在action_down的时候,父类的dispatchtransformedtouchEvent
方法返回false;如果返回true会调用addtouchTarget
方法,给mFirsttouchTarget
设置值:
private touchTarget addtouchTarget(@NonNull VIEw child, int pointerIDBits) { final touchTarget target = touchTarget.obtain(child, pointerIDBits); target.next = mFirsttouchTarget; mFirsttouchTarget = target; return target;}
紧接着在在后面又会调用了:
这句只有在vIEw/vIEwgroup的dispatchtouchEvent
返回false的时候,才会走这里,所以后面的action_move
和action_up
都会走这里,而此时传入的child=null,从上面代码可以看到,直接调用了父类的dispatchtouchEvent
方法。所以从这里不难看出在vIEw/vIEwgroup的dispatchtouchEvent
返回false的时候直接调用了父类的dispatchtouchEvent
方法,因此只有action_down事件。
其实这道题考察大家对vIEw的dispatchtouchEvent和vIEw的ontouchEvent事件的处理流程,上面已经分析了想要vIEw能执行到vIEw的touch事件,那么必须要求vIEw的dispatchtouchEvent
返回true,而dispatchtouchEvent
返回true要么是dispatchtouchEvent
直接返回true或者vIEw的ontouchEvent
返回true。如果从效率上看,直接将dispatchtouchEvent
返回true就ok,而不需要再去关心ontouchEvent
方法。
关于拦截无非就是拦截或不拦截,而拦截的条件是返回true,不拦截是返回false或返回super.onIntercepttouchEvent,默认的super是返回false的,因此可以用super表示不拦截
vIEwgroup拦截实际是通过在dispatchtouchEvent
方法中,设置intercepted变量,如果在拦截方法里面返回true,那么intercepted为true,如果为true则在action_down的时候mFirsttouchTarget=null,那么此时是直接调用dispatchtransformedtouchEvent
传入的child=null,因此将事件交给了super.dispatchtouchEvent
,此时把它当成一个vIEw来处理了。
各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。
点击此处,与我们一起交流学习文件夹有以下学习笔记,自行下载!
BAT大厂面试题、独家面试工具包,
资料免费领取,包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter,
[外链图片转存中…(img-I4VqPb32-1622026312449)]
以上是内存溢出为你收集整理的2021年Android面经分享,赶紧收藏!全部内容,希望文章能够帮你解决2021年Android面经分享,赶紧收藏!所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)