最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司21年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
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的拖拽事件,而不想要view的点击事件,让你重写这个view的拖拽怎么设计
其实这道题考察大家对view的dispatchTouchEvent和view的onTouchEvent事件的处理流程,上面已经分析了想要view能执行到view的touch事件,那么必须要求view的dispatchTouchEvent
返回true,而dispatchTouchEvent
返回true要么是dispatchTouchEvent
直接返回true或者view的onTouchEvent
返回true。如果从效率上看,直接将dispatchTouchEvent
返回true就ok,而不需要再去关心onTouchEvent
方法。
viewgroup拦截
关于拦截无非就是拦截或不拦截,而拦截的条件是返回true,不拦截是返回false或返回super.onInterceptTouchEvent,默认的super是返回false的,因此可以用super表示不拦截
viewgroup拦截实际是通过在dispatchTouchEvent
方法中,设置intercepted变量,如果在拦截方法里面返回true,那么intercepted为true,如果为true则在action_down的时候mFirstTouchTarget=null,那么此时是直接调用dispatchTransformedTouchEvent
传入的child=null,因此将事件交给了super.dispatchTouchEvent
,此时把它当成一个view来处理了。
面试官:有个viewgroup,里面有个view,如果view在dispatchTouchView中不分发事件,并且只在action_move中拦截touch事件向下分发,说说viewgroup到view的各个action是如何分发的?
分析
先贴出事例代码:
testView在testViewgroup里面,testViewgroup在action_move的时候拦截(onInterceptTouchEvent在move返回true),testView不进行分发(dispatchTouchEvent返回true) 咋们通过log来看结果:
这里执行到TestViewgroup#dispatchTouchEvent的action_move之后就执行了TestView#dispatchTouchEvent的action_cancel,然后后面执行TestViewgroup#dispatchTouchEvent和TestViewgroup#onTouchEvent的action_move和action_up。 从前面viewgroup的dispatchTouchEvent分析知道,如果viewgroup在action_down中发现有子view的dispatchTouchEvent返回true,则mFirstTouchTarget
不为空,紧接着在action_move的时候进行了拦截,则intercepted=true,既然在move过程中确定了intercepted=true,mFirstTouchTarget不为空,则可以看viewgroup.dispatchTouchEvent部分代码:
TouchTarget predecessor = null;
TouchTarget target = mFirstTouchTarget;
while (target != null) {
final TouchTarget next = target.next;
//alreadyDispatchedToNewTouchTarget=false
if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
handled = true;
} else {
//由于move过程中intercepted=true,则cancelChild=true
final boolean cancelChild = resetCancelNextUpFlag(target.child)
|| intercepted;
//看到了没这里就是触发child的dispatchTouchEvent的action_cancel
if (dispatchTransformedTouchEvent(ev, cancelChild,
target.child, target.pointerIdBits)) {
handled = true;
}
if (cancelChild) {
if (predecessor == null) {
//由于next=null,因此mFirstTouchTarget=null,所以在action_move刚进来的时候mFirstTouchTarget=null了,
//待会我们通过反射看下该变量
mFirstTouchTarget = next;
} else {
predecessor.next = next;
}
target.recycle();
target = next;
continue;
}
}
predecessor = target;
target = next;
}
复制代码
上面也说明了在action_move进来的时候先是触发了testView#dispatchTouchEvent的action_cancel,紧接着mFirstTouchTarget
=null了,由于mFirstTouchTarget
是viewgroup类中私有的变量,我们可以通过反射调用该变量看下是否为空:
//反射代码,关于反射可以看我之前的文章java反射整理
接着在testViewgroup#dispatchTouchEvent中获取mFirstTouchTarget
属性:
通过上面可以验证刚才move过程中mFirstTouchTarget
为空的判断,日志如下:
看到了没,第一次move的时候mFirstTouchTarget
还不是null,第二次move的时候就是null了,因此在后续的move和up过程中,只会此处:
看到了没,这里传进去的child=null,根据上面分析可知,当为null的时候,只会触发super.dispatchTouchEvent,所以到了第二次的move之后,只能看到TestViewgroup的action_move和action_up了。
所以针对上面面试官提的问题,大家知道怎么说了吧,还是针对该问题做个小结:
小结
先是down事件会经过viewgroup的dispatchTouchEvent,再到viewgroup的onInterceptTouchEvent,最后到view的dispatchTouchEvent,此时mFirstTouchTarget不为空,紧接着到了move首先到viewgroup的dispatchTouchEvent,再到viewgroup的onInterceptTouchEvent,由于在move过程中拦截了,紧接着走view的dispatchTouchEvent的action_cancel,此时接着把mFirstTouchTarget至为null,因此后续的move和up事件只会走viewgroup的dispatchTouchEvent和onTouchEvent。 画出一张图来给大家看下:
好了,关于这个问题告一段落了,如果分析有问题,大家可以提出疑问。
面试官:里面的view在onTouchEvent中消费,然后拖动手指,直到手指从其他他viewgroup上挪开手指。
其实这个问题在上面分析中已经分析过了,testview的onTouchEvent中消费,所以在action_down中mFirstTouchTarget
不为空,因此在action_move和action_up中mFirstTouchTarget
还是不为空,所以不管手指是否已经离开了testview,action_move和action_up还是会走testview的dispatchTouchEvent和onTouchEvent。
小结
首先确定action_down过程中mFirstTouchTarget
是否为空,如果不为空,所以不管手指是否已经不在testView上了,action_move和action_up还是会在testView的onTouchEvent上进行消费的。
最后
希望大家能有一个好心态,想进什么样的公司要想清楚,并不一定是大公司,我选的也不是特大厂。当然如果你不知道选或是没有规划,那就选大公司!希望我们能先选好想去的公司再投或内推,而不是有一个公司要我我就去!还有就是不要害怕,也不要有压力,平常心对待就行,但准备要充足。最后希望大家都能拿到一份满意的 offer !如果目前有一份工作也请好好珍惜好好努力,找工作其实挺累挺辛苦的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!