Android面试题集(三)
自定义View
自定义View的基本方法
自定义View的最基本的三个方法分别是:onMeasure(),onLayout()、onDraw();View在Activity中显示出来,要经历测量、布局、绘制三个步骤,分别对应三个动作:measure、layout和draw。
- 测量:onMeasure()决定View的大小;
- 布局:onLayout()决定View在ViewGroup中的位置;
- 绘制:onDraw()决定绘制这个View。
自定义控件分类
- 自定义View:只需要重写onMeasure()和onDraw()
- 自定义ViewGroup:则只需要重写onMeasure()和onLayout()
View的分类
视图View主要分为两类
类别 | 解释 | 特点 |
---|---|---|
单一视图 | 即一个View,如TextView | 不包含子View |
视图组 | 即多个View组成的ViewGroup,如LinearLayout | 包含子View |
View类简介
- View类是Android中各种组件的基类,如View是ViewGroup基类
- VIew表现为显示在屏幕上的各种视图
Android中的UI组件都由View、ViewGroup组成
- View的构造函数共有4个
AttributeSet与自定义属性
系统自带的View可以在xml中配置属性,对于写的好的自定义View同样可以在xml中配置属性,为了使自定义的View的属性可以在xml中配置,需要以下4个步骤:
1、通过<declare-styleable>为自定义View添加属性
2、在xml中为相应的属性声明属性值
3、在运行时(一般为构造函数)获取属性值
4、将获取到的属性值应用到View
Android坐标系
Android的坐标系定义为:
- 屏幕的左上角为坐标原点
- 向右为x轴增大方向
- 向下为y轴增大方向
位置获取方式
- View的位置是通过view.getxxx()函数进行获取
- 与MotionEvent中get()和getRaw()的区别
get():触摸点相对于其所在的组件坐标系的坐标
event.getX();
event.getY();
getRaw():触摸点相对于屏幕默认坐标系的坐标
event.getRawX();
event.getRawY();
MeasureSpec
测量规格,封装了父容器对View的布局上的限制,内部提供了宽高的信息(SpecMode、SpecSize),SpecSize是指在某种SpecMode下的参考尺寸,其中SpecMode有如下三种:
- UNSPECIFIED 父控件不对你有任何限制,你想要多大给你多大,想上天就上天。这种情况一般用于系统内部,表示一种测量状态。(这个模式主要用于系统内部多次Measure的情形,并不是真的你想要多大最后就真的有多大)
- EXACTLY 父控件已经知道你所需的精确大小,你的最终大小应该就是这么大。
- AT_MOST 你的大小不能大于父控件给你指定的size,但具体是多少,得看你自己的实现。
MeasureSpec的意义
通过将SpecMode和SpecSize打包成一个int值可以避免过多的对象内存分配,为了方便操作,其提供了打包/解包方法。
MeasureSpec值的确定
MeasureSpec值到底是如何计算得来的呢?
image.png
子View的MeasureSpec值是根据子View的布局参数(LayoutParams)和父容器的MeasureSpec值计算得来的,具体计算逻辑封装在getChildMeasureSpec()里
查找算法你用过哪些?
-
查找算法的分类
1、静态查找和动态查找
注:静态或者动态查找都是针对查找表而言的。动态表指查找表中有删除和插入操作的表。
2、无序查找和有序查找
无序查找:被查找数列有序无序均可;
有序查找:被查找数列必须为有序数列。 -
1、顺序查找——复杂度:O(n)
说明:顺序查找适合于存储结构为顺序存储或链接存储的线性表。顺序查找也称为线性查找,属于无需查找算法 -
2、二分查找——复杂度:O(log2n)
说明:元素必须是有序的,如果是无序的则要先进行排序操作。也称为是折半查找,属于有序查找算法。 -
3、插值查找——复杂度:O(log2(log2n))
说明:基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。
注意:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好得多。反之,数组中如果分布非常不均匀,那么插值查找未必使很合适的选择。 -
4、斐波那契查找——复杂度:O(log2n)
说明:也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率,同样地,斐波那契查找也属于一种有序查找算法。 -
5、树表查找之二叉查找树——复杂度:(O(log2n))
说明:二叉查找树是先对待查找的数据进行生成树,确保树的左分支的值小于右分支的值。 -
6、分块查找
说明:分块查找又称索引顺序查找,它是顺序查找的一种改进方法。
7、哈希查找——复杂度:O(1)
说明:通过Hash表进行查找。
什么是IntentService
- 一个封装了HandlerThread和Handler的异步框架。
- 是一种特殊Service,继承自Service,是抽象类,必须创建子类才可以使用。
- 可用于执行后台耗时的任务,任务执行后会自动停止
- 具有高优先级(服务的原因),优先级比单纯的线程高很多,适合高优先级的后台任务,且不容易被系统杀死。
- 启动方式和Service一样。
(1、startService 启动的服务:主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService;
2、bindService 启动的服务:该方法启动的服务可以进行通信。停止服务使用unbindService;
3、startService 同时也 bindService 启动的服务:停止服务应同时使用stepService与unbindService) - 可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandleIntent回调方法中执行。
- 串行执行。
IntentService可以执行大量的耗时操作?
- 如果只有一个任务,是可以进行耗时操作的。
- 如果有很多任务,由于内部的HandlerThread是串行执行任务,会导致耗时操作阻塞了后续任务的执行。
Service和IntentService的区别联系
- Service不是运行在独立的线程,所以不建议在Service中编写耗时的逻辑和操作(必要时,开启独立的线程运行Service),否则会引起ANR。
- IntentService
1、可用于执行后台耗时的任务,任务执行后还会自动停止。
2、具有高优先级,适合高优先级的后台任务,且不容易被系统杀死。
3、可以多次启动,每个耗时操作都会以工作队列的方式在IntentService的onHandlerIntent回调方法中执行。
你了解Lifecycles吗?
官方解释:用于管理Activity和Fragment的生命周期
其实Lifecycles的功能就是使业务组件能够感知Activity和Fragment的生命周期。
什么是databinding?
- 概念
简单来说就是MVVM中ViewModel与Model之间的数据框架
DataBinding是Google官方发布的一个框架,顾名思义就是数据绑定,是MVVM模式在Android上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。MVVM相对于MVP,其实就是将Presenter层替换成了ViewModel层。DataBinding能够省去我们一直以来的findViewById()步骤,大量减少Activity内的代码,数据能够单向或者多向绑定到layout文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常。 -
目前不支持以下操作
1、this
2、super
3、new
4、显示泛型调用
此外,DataBinding还支持一下几种形式的调用Null Coalescing空合并运算符??会取第一个不为null的值作为返回值
image.png - BindingAdapter
dataBinding提供了BindingAdapter这个注解用于支持自定义属性,或者是修改原属性。注解值可以是已有的xml属性,例如android:src、android:text等,也可以自定义属性然后在xml中使用。 - BindingConversion
dataBinding还支持对数据进行转换,或者进行类型转换。
ListView和RecyclerView有什么区别?
- 区别1
ListView:只能在垂直方向滑动。
RecyclerView:支持水平方向滑动,垂直方向滑动,多行多列瀑布流的方式等。 - 区别2
ListView:有几个默认的Adapter,分别是ArrayAdapter、CursorAdapter和SimpleCursorAdaper。
RecyclerView:Adapter需要自己实现。 - 区别3
ListView:拥有子Item的监听函数:AdaperView.OnItemClickListener。
RecyclerView:需要自己实现接口,来实现子Item的点击事件,虽然比较麻烦,但是扩展性好。 - 区别4
ListView:并不强制使用ViewHolder,如果要使用,则需要自己定义,如果不使用,ListView每次getView()的时候都需要findViewById,会造成性能下降,滑动卡顿等,所以推荐使用ViewHolder。
RecyclerView:必须使用ViewHolder。 - 区别5
ListView:两级缓存。
RecyclerView:四级缓存。 - ListView两级缓存
1、mActiveViews用于屏幕内ItemView快速重用
2、mScrapViews用于缓存离开屏幕的ItemView - RecyclerView四级缓存
1、mChangeScrap与mAttachedScrap用于屏幕内ItemView快速重用
2、mCachedViews默认上线为2,即缓存屏幕外2个ItemView
3、mViewCacheExtension用户自定义,一般不使用
4、RecycleViewPool默认上线为5
缓存对象不同,RecyclerView缓存的是ViewHolder,ListView缓存的是View。