【Android】Android UI 绘制相关面试题(一)
1、Android 补间动画和属性动画的区别?
2、Window和DecorView是什么?DecorView又是如何和Window建立联系的?
Window是 WindowManager 最顶层的视图,它负责背景(窗口背景)、Title之类的标准的UI元素, Window是一个抽 象类,整个Android系统中, PhoneWindow是 Window的唯一实现类。至于 DecorView,它是一个顶级 View,内 部会包含一个竖直方向的LinearLayout,这个LinearLayout 有上下两部分,分为 titlebar 和 contentParent两个子元素,contentParent的id是content,而我们自定义的 Activity 的布局就是 contentParent 里面的一个子元素。View 层的所有事件都要先经过 DecorView 后才传递给我们的 View。 DecorView 是 Window 的一个变量,即 DecorView 作为一切视图的根布局,被 Window 所持有,我们自定义的 View 会被添加到 DecorView,而DecorView又会被添加到Window 中加载和渲染显示。
3、简述一下 Android 中 UI 的刷新机制?
界面刷新的本质流程
- 通过ViewRootImpl的 scheduleTraversals()进行界面 的三大流程。
- 调用到scheduleTraversals()时不会立即执行, 而是将该操作保存到待执行队列中。并给底层的刷新信 号注册监听。
- 当 VSYNC信号到来时,会从待执行队列中取出对应的 scheduleTraversals()操作,并将其加入到主线程 的 消息队列中。
- 主线程从 消息队列中取出并执行三大流程: onMeasure()-onLayout()-onDraw()
同步屏障的作用
- 同步屏障用于阻 塞 住所有的同步消息(底层VSYNC 的回调onVsync方法提交的消息是异步消息)
- 用于保证界面刷新功能的performTraversals()的优先执 行。
同步屏障的原理?
- 主线程的Looper会一直循环调用MessageQueue的 next方法并且取出队列头部的Message执行,遇到同步 屏障(一种特殊消息)后会去寻找异步消息执行。如果没 有找到异步消息就会一直阻塞下去,除非将同步屏障 取出,否则永远不会执行同步消息。
- 界面刷新操作是异步消息,具有最高优先级
- 我们发送的消息是同步消息,再多耗时操作也不会影响UI的刷新操作
4、LinearLayout, FrameLayout,RelativeLayout 哪个效率高, 为什么?
对于比较三者的效率那肯定是要在相同布局条件下比较绘制的流畅度及绘制过程,在这里流畅度不好表达,并且受其 他外部因素干扰比较多,比如CPU、GPU等等,我说下在绘制过程中的比较
Fragment是从上到下的一个堆 叠的方式布局的,那当然是绘制速度最快,只需要将本身绘制出来即可,但是由于它的绘制方式导致在复杂场景中直接是不能使用的,所以工作效率来说Fragment仅使用于 单一场景
LinearLayout 在两个方向上绘制的布局,在工作中使用页比较多,绘制的时候只需要按照指定的方向绘制,绘制效率比Fragment要慢,但使用场景比较多,
RelativeLayout 它的没个子控件都是需要相对的其他控件来计算,按照View树的绘制流程、在不同的分支上要进行计算相对应的位置,绘制效率最低,但是一般工作中的 布局使用较多,所以说这三者之间效率分开来讲个有优势、不足,那一起来讲也是有优势、不足,所以不能绝对的区分三者的效率
5、谈谈Android的事件分发机制?
当点击的时候,会先调用顶级viewgroup的dispatchTouchEvent,如果顶级的viewgroup拦截了此事件 (onInterceptTouchEvent返回true),则此事件序列 由顶级viewgroup处理。如果顶级viewgroup设置 setOnTouchListener,则会回调接口中的onTouch,此时顶级的viewgroup中的onTouchEvent不再回调,如果不设 置 setOnTouchListener则onTouchEvent会回调。如果顶级viewgroup设置setOnClickListener,则会回调接口中的 onClick。如果顶级viewgroup不拦截事件,事件就会向下传递给他的子view,然后子view就会调用它的 dispatchTouchEvent方法。
6、针对RecyclerView你做了哪些优化?
- onBindViewHolder. 这个方法含义应该都知道是绑定数据,并且是在UI线程,所以要尽量在这个方法中少做一些业务处理
- 数据优化. 采用androidSupport 包下的DIffUtil集合工具类结合RV分页加载会更加友好,节省性能
- item优化. 减少item的View的层级,(pps:当然推荐把一个item自定义成一个View,如果有能力的话),如果item的高度固定的话可以设置setHasFixedSize(true),避免requestLayout浪费资源
- 使用RecycledViewPool. RecycledViewPool是对item进行缓存的,item相同的不同RV可以才使用这种方式进行性能提升
- Prefetch预取.这是在RV25.1.0及以上添加的新功能,预取详情资源回收. 过重写RecyclerView.onViewRecycled(holder)来合理的回收资源
7、谈谈如何优化ListView?
#android面试#ViewHolder什么的持有View预加载/懒加载数据什么的 大招:用RecyclerView替换ListView 绝招:直接删除控件