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. C语言函数以及函数的使用
  2. Android监听应用程序安装和卸载
  3. Android应用程序安装过程源代码分析(3)
  4. Android应用程序安装过程源代码分析(4)
  5. Android为每个应用程序分配的内存大小是多
  6. Android实现自己的回调函数
  7. Android应用程序键盘(Keyboard)消息处理机制分析(12)
  8. Android应用程序的四个关键点
  9. android实现应用程序的开机自启动

随机推荐

  1. android 背景resource资源文件使用整理
  2. Android4.4 窗口添加过程
  3. android实现图片触摸旋转
  4. Android(安卓)studio下运行百度地图demo
  5. 现在跨平台开发(手机平台,主要是Android、i
  6. Android三种实现自定义ProgressBar的方式
  7. eclipse 中 Android(安卓)项目依赖文件管
  8. Android实现数据存储5种技术
  9. Android——添加屏幕待机选项
  10. Android下拉状态栏快捷开关的添加