Android应用程序键盘(Keyboard)消息处理机制分析(26)
Step 7.LocalWindowManager.removeViewImmediate
这个函数定义在frameworks/base/core/java/android/view/Window.java文件中:
- publicabstractclassWindow{
- ......
- privateclassLocalWindowManagerimplementsWindowManager{
- ......
- publicfinalvoidremoveViewImmediate(Viewview){
- mWindowManager.removeViewImmediate(view);
- }
- ......
- privatefinalWindowManagermWindowManager;
- }
- ......
- }
LocalWindowManager类的成员变量mWindowManager是一个WndowManagerImpl对象,这个函数只是简单地调用WndowManagerImpl类的removeViewImmediate来进一步处理。
Step 8.WndowManagerImpl.removeViewImmediate
这个函数定义在frameworks/base/core/java/android/view/WindowManagerImpl.java文件中:
- publicclassWindowManagerImplimplementsWindowManager{
- ......
- publicvoidremoveViewImmediate(Viewview){
- synchronized(this){
- intindex=findViewLocked(view,true);
- ViewRootroot=mRoots[index];
- ......
- root.die(true);
- ......
- }
- }
- ......
- }
这个函数首先是找到这个view所属的ViewRoot对象root,然后调用这个root对象的die函数来销毁它。
Step 9. ViewRoot.die
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- publicvoiddie(booleanimmediate){
- if(immediate){
- doDie();
- }else{
- ......
- }
- }
- ......
- }
上面Step 8传进来的immediate参数为true,因此,这里直接调用doDie函数来进一步处理。
Step 10.ViewRoot.doDie
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- voiddoDie(){
- ......
- synchronized(this){
- ......
- if(mAdded){
- mAdded=false;
- dispatchDetachedFromWindow();
- }
- }
- }
- ......
- }
当我们把Activity窗口中的View添加到一个ViewRoot对象时,就会把它的成员变量mAdded设置为true,这样就表示这个ViewRoot中有View存在,于是,这里就会调用dispatchDetachedFromWindow函数来进一步处理。
Step 11.ViewRoot.ispatchDetachedFromWindow
这个函数定义在frameworks/base/core/java/android/view/ViewRoot.java文件中:
- publicfinalclassViewRootextendsHandlerimplementsViewParent,
- View.AttachInfo.Callbacks{
- ......
- voiddispatchDetachedFromWindow(){
- ......
- if(mInputChannel!=null){
- if(mInputQueueCallback!=null){
- ......
- }else{
- InputQueue.unregisterInputChannel(mInputChannel);
- }
- }
- try{
- sWindowSession.remove(mWindow);
- }catch(RemoteExceptione){
- }
- ......
- }
- ......
- }
前面在介绍应用程序注册键盘消息接收通道的过程时,在Step 18,我们说到,ViewRoot类中的mInputQueueCallback为null,表示由这个ViewRoot自己来管理键盘输入事件,因此,这里首先会调用InputQueue的unregisterInputChannel函数来注销注册在应用程序这一侧的Client端InputChannel,然后再调用sWindowSession的remove函数来注销注册在InputManager这一侧的Server端InputChannel,这个逻辑是和前面介绍应用程序注册键盘消息接收通道的逻辑相对应的,前面分别注册了这两个InputChannel,现在Activity要销毁了,当然就要把它们注销了。
我们先来看注销注册在应用程序这一侧的Client端InputChannel,然后再回过头来分析注销注册在InputManager这一侧的Server端InputChannel。
Step 12.InputQueue.unregisterInputChannel
这个函数定义在frameworks/base/core/java/android/view/InputQueue.java文件中:
- publicfinalclassInputQueue{
- ......
- publicstaticvoidunregisterInputChannel(InputChannelinputChannel){
- ......
- synchronized(sLock){
- ......
- nativeUnregisterInputChannel(inputChannel);
- }
- }
- ......
- }
这个函数只是简单地调用本地方法nativeUnregisterInputChannel来执行具体的操作。
Step 13.InputQueue.nativeUnregisterInputChannel
这个函数定义在frameworks/base/core/jni/android_view_InputQueue.cpp文件中:
- staticvoidandroid_view_InputQueue_nativeUnregisterInputChannel(JNIEnv*env,jclassclazz,
- jobjectinputChannelObj){
- status_tstatus=gNativeInputQueue.unregisterInputChannel(env,inputChannelObj);
- ......
- }
这里调用NativeInputQueue的成员函数unregisterInputChannel来进一步处理。
更多相关文章
- C语言函数以及函数的使用
- android intent.setType指定浏览本地多种类型的文件
- Android 通过继承TextView类自定义字体默认颜色
- 自己定义的Tabhost
- android 自定义对话框 背景透明
- 修改文件夹权限
- Android——文件操作
- Android下使用Properties文件保存程序设置
- android解析xml文件 Android DOM解析XML之全球实时地震信息列表