【Android】Android UI 绘制相关面试题(三)
1、请谈谈View.inflate和LayoutInflater.inflate的区别?
实际上没有区别
- View.inflate实际上是对LayoutInflater.inflate做了一层包装,在功能上,LayoutInflate功能更加强大。
- View.inflate实际上最终调用的还是LayoutInflater.inflate(@LayoutRes int resource,@nullable ViewGroup root)三个参数的方法,这里如果传入的root如果不为空,那么解析出来的View会被添加到这个ViewGroup当中去。
- 而LayoutInflater.inflate方法则可以指定当前View是否需要添加到ViewGroup中去
2、请谈谈invalidate()和postInvalidate() 方法的区别和应用场景?
- invalidate()用来重绘UI,需要在UI线程调用。
- postInvalidate()也是用来重新绘制UI,它可以在UI线程调 用,也可以在子线程中调用,postInvalidate()方法内部通过Handler发送了一个消息将线程切回到UI线程通知重新绘制,并不是说postInvalidate()可以在子线程更新UI,本质上还是在UI线程发生重绘,只不过我们使用postInvalidate()它内部会帮我们切换线程
3、谈一谈SurfaceView与TextureView的使用场景和用法?
- 频繁绘制和对帧率要求比较高的需求,比如拍照、视频和游戏等
- SurfaceView有独立的绘图表面,可以在子线程中进行绘制, 缺点是不能够执行平移、缩放、旋转、透明渐变操作,TextureView的出现就是为了解决这些问题
- SurfaceView的使用方法,大概是获取SurfaceHolder 对象,监听surface创建,更新,销毁,创新一个新的线程,并在其中绘制并提交
- TextureView并没有独立的绘图表面,在使用过程中, 需要添加监听surfaceTexture是否可用,再做相应的处理
4、谈一谈RecyclerView.Adapter的几种刷新方式有何不同?
刷新全部可见的item,notifyDataSetChanged() 刷新指定item,notifyItemChanged(int) 从指定位置开始刷新指定个item,notifyItemRangeChanged(int,int)插入、移动一个并自动刷新,notifyItemInserted(int)、notifyItemMoved(int)、notifyItemRemoved(int) 局部刷新,notifyItemChanged(int, Object)
5、有了解过WindowInsets吗?它有哪些应用?
ViewRootImpl在performTraversals时会调dispatchApplyInsets,内调DecorViewdispatchApplyWindowInsets,进行WindowInsets的分发。
6、请谈谈什么是同步屏障?
handler.getLooper().getQueue().postSyncBarrier()加入同步屏障后,Message.obtain()获取一个target为null的msg,并根据当前时间将该msg插入到链表中。在Looper.loop()循环取消息中 Message msg = queue.next(); target为空时,取链表中的异步消息。通过setAsynchronous(true)来指定为异步消息应用场景:ViewRootImpl scheduleTraversals中加入同步屏障并在view的绘制流程中post异步消息,保证view的绘制消息优 先执行
7、谈一谈屏幕刷新机制?
#android面试#屏幕刷新频率和绘制频率cpu负责 measurelayoutdraw =>displayListgpu 负责 display => 位图每个16ms会发送一次垂直同步信号, vsync每次信号发送的时候都会从gpu的buffer中取出渲染好的位图显示在屏幕上,同时如果有需要 还会进行下一次的 cpu计算,计算好后放入buffer中,如果计算时间超过了两次vsync之间的时间 ,即16ms ,则vsync信号会把 上一次gpu buffer中的信息展示出来,这时候就是卡顿,另外如果页面没有变化 屏幕还是一样会去buffer中取出上一次的刷新,只不过cpu不再去计算而已