题解乃见仁见智之事,以下只是自己的看法,仅供参考,因本人水平有限,如有问题欢迎指正。
之所以是题解1.0,是希望随着学习的深入,以后能更深刻的理解,再出个题解2.0最好不过了。
以下为作者文章中部分内容。
2、View 相关题解
Q:MotionEvent是什么?包含几种事件?什么条件下会产生?
技术点:View触控
参考回答:MotionEvent是手指触摸屏幕锁产生的一系列事件。包含的事件有:
Q:scrollTo()和scrollBy()的区别?
技术点:View滑动
参考回答:scrollBy内部调用了scrollTo,它是基于当前位置的相对滑动;而scrollTo是绝对滑动,因此如果利用相同输入参数多次调用scrollTo()方法,由于View初始位置是不变只会出现一次View滚动的效果而不是多次。
引申:两者都只能对view内容进行滑动,而不能使view本身滑动,且非平滑,可使用Scroller有过渡滑动的效果
Q:Scroller中最重要的两个方法是什么?主要目的是?
技术点:View滑动
思路:从Scroller实现滑动的具体过程出发,
参考回答:Scroller实现滑动的具体过程:
其中,最重要的两个方法是startScroll()和computeScroll()
Q:谈一谈View的事件分发机制?
技术点:View事件分发
思路:从分发本质、传递顺序、核心方法展开
参考回答:
事件分发本质:就是对MotionEvent事件分发的过程。即当一个MotionEvent产生了以后,系统需要将这个点击事件传递到一个具体的View上。
点击事件的传递顺序:Activity(Window) -> ViewGroup -> View
三个主要方法:
Q:如何解决View的滑动冲突?
技术点:View滑动冲突
思路:从处理规则和具体实现方法展开讨论
参考回答:
(1)处理规则:
(2)实现方法:
Q:谈一谈View的工作原理?
技术点:View工作流程
思路:围绕三大流程展开
参考回答:View工作流程简单来说就是,先measure测量,用于确定View的测量宽高,再 layout布局,用于确定View的最终宽高和四个顶点的位置,最后 draw绘制,用于将View 绘制到屏幕上。具体过程图见:
ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带。
View的绘制流程是从ViewRoot和performTraversals开始。
performTraversals()依次调用performMeasure()、performLayout()和performDraw()三个方法,分别完成顶级 View的绘制。
其中,performMeasure()会调用measure(),measure()中又调用onMeasure(),实现对其所有子元素的measure过程,这样就完成了一次measure过程;接着子元素会重复父容器的measure过程,如此反复至完成整个View树的遍历。layout和draw同理。
Q:MeasureSpec是什么?有什么作用?
技术点:View工作流程(measure)
思路:从MeasureSpec作用、组成、模式和决定因素展开
参考回答:
作用:通过宽测量值widthMeasureSpec和高测量值heightMeasureSpec决定View的大小
组成:一个32位int值,高2位代表SpecMode(测量模式),低30位代表SpecSize( 某种测量模式下的规格大小)。
三种模式:
决定因素:值由子View的布局参数LayoutParams和父容器的MeasureSpec值共同决定。具体规则见下图:
引申:直接继承View的自定义View需要重写onMeasure()并设置wrap_content时的自身大小,否则效果相当于macth_parent。
Q:自定义View/ViewGroup需要注意什么?
技术点:自定义View
参考回答:
Q:onTouch()、onTouchEvent()和onClick()关系?
技术点:View事件分发
参考回答:优先度onTouch()>onTouchEvent()>onClick()。因此onTouchListener的onTouch()方法会先触发;如果onTouch()返回false才会接着触发onTouchEvent(),同样的,内置诸如onClick()事件的实现等等都基于onTouchEvent();如果onTouch()返回true,这些事件将不会被触发。
引申:OnTouchListener、OnClickListener的冲突
Q:SurfaceView和View的区别?
技术点:View、SurfaceView
参考回答:SurfaceView是从View基类中派生出来的显示类,他和View的区别有:
Q:invalidate()和postInvalidate()的区别?
技术点:View刷新
参考回答:invalidate()与postInvalidate()都用于刷新View,主要区别是invalidate()在主线程中调用,若在子线程中使用需要配合handler;而postInvalidate()可在子线程中直接调用。
3、线程相关题解
Q:Android中还了解哪些方便线程切换的类?
技术点:线程通信
参考回答:对Handler进一步的封装的几个类:
引申:更多是对消息机制的理解
Q:AsyncTask相比Handler有什么优点?不足呢?
技术点:AsyncTask、Handler
参考回答:
Handler机制存在的问题:多任务同时执行时不易精确控制线程。
引入AsyncTask的好处:创建异步任务更简单,直接继承它可方便实现后台异步任务的执行和进度的回调更新UI,而无需编写任务线程和Handler实例就能完成相同的任务。
Q:使用AsyncTask需要注意什么?
技术点:AsyncTask
参考回答:
引申:谈谈AsyncTask初始化、五个核心方法如何配合进而体现Handler的作用
Q:AsyncTask中使用的线程池大小?
技术点:AsyncTask
参考回答:在AsyncTask内部实现有两个线程池:
引申:谈谈对线程池的理解
Q:HandlerThread有什么特点?
技术点:HandlerThread
参考回答:HandlerThread是一个线程类,它继承自Thread。与普通Thread不同,HandlerThread具有消息循环的效果,这是因为它内部HandlerThread.run()方法中有Looper,能通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。
Q:快速实现子线程使用Handler
技术点:HandlerThread
思路:不同于之前手动在子线程创建Looper再构建Handler的想法,这里从HandlerThread角度去快速实现在子线程使用Handler
参考回答:HandlerThread实现方法
Q:IntentService的特点?
技术点:IntentService
思路:和普通线程和普通Service比较突出其特点
参考回答: 不同于线程,IntentService是服务,优先级比线程高,更不容易被系统杀死,因此较适合执行一些高优先级的后台任务;不同于普通Service,IntentService可自动创建子线程来执行任务,且任务执行完毕后自动退出。
Q:为何不用bindService方式创建IntentService?
技术点:IntentService
思路:从底层实现出发
参考回答:IntentService的工作原理是,在IntentService的onCreate()里会创建一个HandlerThread,并利用其内部的Looper实例化一个ServiceHandler对象;而这个ServiceHandler用于处理消息的handleMessage()方法会去调用IntentService的onHandleIntent(),这也是为什么可在该方法中处理后台任务的逻辑;当有Intent任务请求时会把Intent封装到Message,然后ServiceHandler会把消息发送出,而发送消息是在onStartCommand()完成的,只能通过startService()才可走该生命周期方法,因此不能通过bindService创建IntentService。
Q:线程池的好处、原理、类型?
技术点:线程池
参考回答:
(1)线程池的好处:
(2)线程池的分类:
(3)线程池的原理:实际上通过ThreadPoolExecutor并通过一系列参数来配置各种各样的线程池,具体的参数有:
引申:使用Executors各个方法创建线程池的弊端
https://www.jianshu.com/p/4b89d681c5a0
Q:ThreadPoolExecutor的工作策略?
技术点:线程池
参考回答:ThreadPoolExecutor的默认工作策略:
引申:ThreadPoolExecutor的拒绝策略
4、IPC相关题解
Q:Android中进程和线程的关系?
技术点:进程、线程
参考回答:
Q:为何需要进行IPC?多进程通信可能会出现什么问题?
技术点:多进程通信
思路:讨论多进程通信会出现的问题得出IPC的必要性
参考回答:
(1)多进程造成的影响可总结为以下四方面:
(2)需要进程间通信的必要性:所有运行在不同进程的四大组件,只要它们之间需要通过内存在共享数据,都会共享失败。这是由于Android为每个应用分配了独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这会导致在不同的虚拟机中访问同一个类的对象会产生多份副本。
引申: 谈谈IPC的使用场景
Q:什么是序列化?Serializable接口和Parcelable接口的区别?为何推荐使用后者?
技术点:序列化
参考回答:序列化表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
应用场景:需要通过Intent和Binder等传输类对象就必须完成对象的序列化过程。
两种方式:实现Serializable/Parcelable接口。不同点如图:
Q:Android中为何新增Binder来作为主要的IPC方式?
技术点:Binder机制
思路:回答Binder优点
参考回答:Binder机制有什么几条优点:
1. 传输效率高、可操作性强:传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。从Android进程架构角度分析:对于消息队列、Socket和管道来说,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到接收方的缓存区,一共两次拷贝,如图:
而对于Binder来说,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同一块物理地址的,节省了一次数据拷贝的过程,如图:
由于共享内存操作复杂,综合来看,Binder的传输效率是最好的。
2. 实现C/S架构方便:Linux的众IPC方式除了Socket以外都不是基于C/S架构,而Socket主要用于网络间的通信且传输效率较低。Binder基于C/S架构 ,Server端与Client端相对独立,稳定性较好。
3. 安全性高:传统Linux IPC的接收方无法获得对方进程可靠的UID/PID,从而无法鉴别对方身份;而Binder机制为每个进程分配了UID/PID且在Binder通信时会根据UID/PID进行有效性检测。
Q:使用Binder进行数据传输的具体过程?
技术点:Binder机制
思路:通过AIDL实现方式解释Binder数据传输的具体过程
参考回答:服务端中的Service给与其绑定的客户端提供Binder对象,客户端通过AIDL接口中的asInterface()将这个Binder对象转换为代理Proxy,并通过它发起RPC请求。客户端发起请求时会挂起当前线程,并将参数写入data然后调用transact(),RPC请求会通过系统底层封装后由服务端的onTransact()处理,并将结果写入reply,最后返回调用结果并唤醒客户端线程。
Q:Binder框架中ServiceManager的作用?
技术点:Binder机制
思路:从Binder框架出发讨论每个元素的作用
参考回答:在Binder框架定义了四个角色:Server,Client,ServiceManager和Binder驱动。其中Server、Client、ServiceManager运行于用户空间,Binder驱动运行于内核空间。关系如图:
Binder驱动:
Q:Android中有哪些基于Binder的IPC方式?简单对比下?
技术点:IPC方式
思路:分析每种IPC方式的优缺点和使用场景的差异
参考回答:
Q:是否了解AIDL?原理是什么?如何优化多模块都使用AIDL的情况?
技术点:AIDL
参考回答:
工作原理:每个业务模块创建自己的AIDL接口并实现此接口,然后向服务端提供自己的唯一标识和其对应的Binder对象。服务端只需要一个Service,服务器提供一个queryBinder接口,它会根据业务模块的特征来返回相应的Binder对像,不同的业务模块拿到所需的Binder对象后就可进行远程方法的调用了。
流程如图:
由于篇幅原因,以上仅为一小部分,原文非常长,各位刻意仔细阅读作者原文。
下面三篇该为面试总结题解了:
2019 Android 秋招提前批面试总结
按字母顺序浏览:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
→我们致力于为广大网民解决所遇到的各种电脑技术问题 如果您认为本词条还有待完善,请 编辑词条