#总结
总得来说问题比较大,很多问到的问题没有打出来,还有一些应该能回答的问题没有回答到点子上。
一个可能是因为之前一直在准备托福,Android有些生疏;另外就是有点自满了,面试之前还有一天多的时间也没有好好准备,之前一面回答的不好的题也没有搞清楚。
#问题
##1. 说一下对Android的理解
这个问题完全在我意料之外,实在是有些大。我就从我知道的开始扯:Android基于Linux,启动方式是从Zygote(面试的时候错误的说成dalvik) folk新的进程来承载app。
然后讲到Android runtime从Dalvik转变到现在新的ART,区别在于Dalvik是JIT而ART是AOT。
##2. Handler是怎么工作的?postDelayed是如何实现的?消息移除是怎么实现的?
这个问题一面的时候问到了,当时回答的不是特别好,但是没有引起足够的重视。
下面摘抄几个概念:
* Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
* Message Queue 消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
* Handler Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
* Looper 循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
* 线程 UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。
Looper实际上就是消息队列+消息循环的封装。
Handler可以被看做Looper的接口,用来向指定的Looper发送消息以及定义处理方法。
Hander handler=new Handler();等价于Handler handler=new Handler(Looper.myLooper());
Looper.prepare(): 创建looper,新建messagequeue,并将looper对象装入ThreadLocal中。
Looper.loop(): 让Looper开始工作,infinite loop,取messagequeue的下一个message对象
通过查阅源码,我发现postDelayed会被传递给messageQueue的queue.enqueueMessage(msg, uptimeMillis),这里的时间会是当前时间加上delay的时间,之后这个时间会被设置为message.when
而在messagequeue的next()方法中:
可以看到取下一个message时会判断时间,如果队列中没有消息或者第一个待处理的消息时机未到,且也没有其他利用队列空闲要处理的事务,则将队列设置为设置 blocked 状态,进入等待状态;否则就利用队列空闲处理其它事务。
enqueueMessage会根据when把新入的message放在合适的位置;removeMessage会遍历整条queue移除符合要求的message
reference
##3. Binder&&IPC的实现原理
binder其实不是android首先提出来的IPC机制,它是基于OpenBinder来实现的。OpenBinder有许可问题,andriod不能直接使用,故此重新开发了自己的一套binder实现,基于宽松的Apache协议发布,架构与OpenBinder类似,相关信息可以参考: http://www.open-binder.org。
这个问题还没有研究透彻,先留下一个reference
##4. Activity如何收到Touch事件
在ViewRootImpl的setView方法中,用户的触摸按键消息是体现在窗体上的,而windowManagerService则是管理这些窗口,它一旦接收到用户对窗体的一些触摸按键消息,会进行相应的动作,这种动作是需要体现在具体的view上面,在Android中,一个具体的界面是由一个Activity呈现的,而Activity中则包含了一个window,此window中又包含了一个phoneWindow,这个phoneWindow才是真正意义上的窗口,它把一个框架布局进行了一定的包装,并提供了具体的窗口操作接口,phoneWindow中包含了一个DecorView,这个view才是包含整个Activity的ui,它将被attach到Activity主窗口中。所以说用户触摸按键的消息是由windowManagerService捕捉到然后交给phoneWindow中的DecorView进行相应的处理,而连接两者的桥梁则是一个ViewRoot类,ViewRoot类由windowManagerService创建,其内部有一个W类,这个W类是一个binder,负责WindowManagerService的ipc调用,W接收到windowManagerService发送过来的消息后,把消息传递给ViewRoot,进而传递给ActivityThread解析做出处理。
reference
##5. 什么是NIO
非阻塞的I/O交互。通道是对原I/O包的流的模拟,缓冲区是一个容器对象,发送给一个通道的所有对象必须先放到缓冲区中;从通道中读取的数据都要读到缓冲区中。
* 容量:Capacity
* 上界:Limit
* 位置:Position
* 标记:Mark
0 <= mark <= position <= limit <= capacity
reference