Step 19. InputManager.unregisterInputChannel

这个函数定义在frameworks/base/services/java/com/android/server/InputManager.java文件中:

  1. publicclassInputManager{
  2. ......
  3. publicvoidunregisterInputChannel(InputChannelinputChannel){
  4. ......
  5. nativeUnregisterInputChannel(inputChannel);
  6. }
  7. ......
  8. }

这个函数很简单,它调用本地方法nativeUnregisterInputChannel来进一步处理。

Step 20.InputManager.nativeUnregisterInputChannel

这个函数定义在frameworks/base/services/jni/com_android_server_InputManager.cpp文件中:

  1. staticvoidandroid_server_InputManager_nativeUnregisterInputChannel(JNIEnv*env,jclassclazz,
  2. jobjectinputChannelObj){
  3. ......
  4. sp<InputChannel>inputChannel=android_view_InputChannel_getInputChannel(env,
  5. inputChannelObj);
  6. ......
  7. status_tstatus=gNativeInputManager->unregisterInputChannel(env,inputChannel);
  8. ......
  9. }

这个函数首先调用android_view_InputChannel_getInputChannel函数根据Java层的InputChannel对象找到C++层的InputChannel对象,然后调用NativeInputManager的unregisterInputChannel函数来执行注销的操作。

Step 21.NativeInputManager.unregisterInputChannel
这个函数定义在frameworks/base/services/jni/com_android_server_InputManager.cpp文件中:

  1. status_tNativeInputManager::unregisterInputChannel(JNIEnv*env,
  2. constsp<InputChannel>&inputChannel){
  3. ......
  4. returnmInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
  5. }

这个函数与前面分析应用程序注册键盘消息通道的Step 17(NativeInputManager.registerInputChannel)相对应,主要是调用InputDispatcher对象的unregisterInputChannel函数来执行真正注销的操作。

Step 22.InputDispatcher.unregisterInputChannel
这个函数定义在frameworks/base/libs/ui/InputDispatcher.cpp文件中:

  1. status_tInputDispatcher::unregisterInputChannel(constsp<InputChannel>&inputChannel){
  2. ......
  3. {//acquirelock
  4. AutoMutex_l(mLock);
  5. ssize_tconnectionIndex=getConnectionIndexLocked(inputChannel);
  6. ......
  7. sp<Connection>connection=mConnectionsByReceiveFd.valueAt(connectionIndex);
  8. mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
  9. ......
  10. mLooper->removeFd(inputChannel->getReceivePipeFd());
  11. .....
  12. }//releaselock
  13. ......
  14. returnOK;
  15. }

这一步与前面的Step 14注销应用程序一侧的Client端InputChannel是差不多的,只不过这里是从InputDispatcher中把Server端的InputChannel注销掉。首先是根据传进来的参数inputChannel找到它在InputDispatcher中对应的Connection对象在mConnectionsByReceiveFd中的索引,然后把它从mConnectionsByReceiveFd中删除:

  1. ssize_tconnectionIndex=getConnectionIndexLocked(inputChannel);
  2. ......
  3. sp<Connection>connection=mConnectionsByReceiveFd.valueAt(connectionIndex);
  4. mConnectionsByReceiveFd.removeItemsAt(connectionIndex);

最后,还需要把这个InputChannel中的反向管道读端文件描述符从InputDispatcher的内部对象mLooper中删除,因为这个文件描述符是在前面注册Server端的InputChannel时加入到mLooper对象去的,具体可以参考上面分析应用程序注册键盘消息接收通道的过程中的Step 18(InputDispatcher.registerInputChannel)。

这样,应用程序注销键盘消息接收通道的过程就分析完成了,整个应用程序键盘消息处理机制也分析完成了,这是一个比较复杂的过程,要完全理解它还需要花费一些努力和时间,不过,理解了这个过程之后,对Android应用程序框架层的理解就更进一步了。

更多相关文章

  1. Android应用程序安装过程源代码分析(3)
  2. 【翻译】(1)何为Android?(2012-06-30废弃)
  3. Android获取手机信息
  4. Android(安卓)NDK 开发
  5. Android应用程序安装过程源代码分析(4)
  6. 几个activity跳转特效的实现
  7. FregServer进程,返回BR_REPLY
  8. Android实现自己的回调函数
  9. android属性

随机推荐

  1. 【Android】简单实现拷贝文件和文件夹到
  2. Android(安卓)JNI的调用过程
  3. 使用eclipse搭建android开发环境
  4. android分辨率与尺寸适配,UI切图方法
  5. Android(安卓)L下用XXRadius设置圆角背景
  6. Android中WebView用法实例分析
  7. Android快速开发框架——Afinal 0.5 发布
  8. Android(安卓)Studio中生成aar之包括*.ja
  9. [android之旅]环境搭建中的一些问题
  10. Android后台推送摄像头/屏幕数据