软键盘
2017-03-18 本文已影响0人
Mr_468
http://blog.csdn.net/innost/article/details/47660591
http://blog.csdn.net/luoshengyang/article/details/6882903
安卓系统启动流程中,SystemManagerService启动WindowManagerService负责窗口管理,WindowManagerService启动InputManger负责键盘管理。
activity的启动过程中,ActivityThread中handleLaunchActivity调用performLaunchActivity加载完activity对象之后返回handleLaunchActivity方法,接着调用handleResumeActivity使activity进驻resumed状态。handleResumeActivity函数里ActivityThread将DecorView添加到WindowManagerImpl的mViews中,创建一个mViewRoot实例,Activity通过mViewRoot与WindowManagerService进行消息传递,处理viewTree的各种事件。
ViewRoot的setView方法干了三件事
- 将被激活的Activity窗口,会通知InputManager,它是当前激活的窗口,因此,一旦发生键盘事件的时候,InputManager就把这个键盘事件抛给这个Activity处理;
- 应用程序会为这个Activity窗口和InputManager之间创建一个键盘消息接收通道,这个通道的一端由一个Server端的InputChannel构成,另一端由Client端的InputChannel构成,Server端的InputChannel注册在由InputManager所管理的InputDispatcher中,而Client端的InputChannel注册在由应用程序主线程的消息循环对象Looper中;
- 注册在InputDispatcher中的InputChannel由一个反向管道的读端和一个前向管道的写端组成,而注册在应用程序主线程的消息循环对象Looper中的InputChannel由这个前向管道的读端和反向管道的写端组成,这种交叉结构使得当有键盘事件发生时,InputDispatcher可以把这个事件通知给应用程序。
应用程序注册好键盘消息接收通道后,接下来就开始分析InputManager分发键盘消息给应用程序的过程了。
- 键盘事件发生,InputManager中的InputReader被唤醒,此前InputReader睡眠在/dev/input/event0这个设备文件上;
- InputReader被唤醒后,它接着唤醒InputManager中的InputDispatcher,此前InputDispatcher睡眠在InputManager所运行的线程中的Looper对象里面的管道的读端上;
- InputDispatcher被唤醒后,它接着唤醒应用程序的主线程来处理这个键盘事件,此前应用程序的主线程睡眠在Client端InputChannel中的前向管道的读端上;
- 应用程序处理处理键盘事件之后,它接着唤醒InputDispatcher来执行善后工作,此前InputDispatcher睡眠在Server端InputChannel的反向管道的读端上,注意这里与第二个线索处的区别。
当Activity窗口创建时,它会向InputManager注册键盘消息接收通道,而当Activity窗口销毁时,它就会向InputManager注销前面注册的键盘消息接收通道了。