Android应用程序键盘(Keyboard)消息处理机制分析(24)
4.应用程序注销键盘消息接收通道的过程分析 当Activity窗口创建时,它会向InputManager注册键盘消息接收通道,而当Activity窗口销毁时,它就会向InputManager注销前面注册的键盘消息接收通道了,本节内容就来看看应用程序注销键盘消息接收通道的过程。 当我们按下键盘上的Back键时,当前激活的Activity窗口就会被失去焦点,但是这时候它还没有被销毁,它的状态被设置为Stopped;当新的Activity窗口即将要显示时,它会通知WindowManagerService,这时候WindowManagerService就会处理当前处理Stopped状态的Activity窗口了,要执行的操作就是销毁它们了,在销毁的时候,就会注销它们之前所注册的键盘消息接收通道。 新的Activity窗口通知WindowManagerService它即将要显示的过程比较复杂,但是它与我们本节要介绍的内容不是很相关,因此,这里就略过大部过程了,我们从ActvitiyRecord的windowsVisible函数开始分析。注意,这里的ActivityRecord是新的Activity窗口在ActivityManangerService的代表,而那些处于Stopped状态的Activity窗口 会放在ActivityStack类的一个等待可见的mWaitingVisibleActivities列表里面,事实于,对于那些Stopped状态的Activity窗口来说,它们是等待销毁,而不是等待可见。 像前面一样,我们先来看一张应用程序注销键盘消息接收通道的过程的序列图,然后根据这个序列图来详细分析互一个步骤: Step 1. ActivityRecord.windowsVisible 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityRecord.java文件中: classActivityRecordextendsIApplicationToken.Stub{ ...... booleannowVisible;//isthisactivity'swindowvisible? booleanidle;//hastheactivitygoneidle? ...... publicvoidwindowsVisible(){ synchronized(service){ ...... if(!nowVisible){ nowVisible=true; if(!idle){ ....... }else{ //Ifthisactivitywasalreadyidle,thenwenowneedto //makesureweperformthefullstopofanyactivities //thatarewaitingtodoso.Thisisbecausewewon't //dothatwhiletheyarestillwaitingforthisoneto //becomevisible. finalintN=stack.mWaitingVisibleActivities.size(); if(N>0){ for(inti=0;i<N;i++){ ActivityRecordr=(ActivityRecord) stack.mWaitingVisibleActivities.get(i); r.waitingVisible=false; ...... } stack.mWaitingVisibleActivities.clear(); Messagemsg=Message.obtain(); msg.what=ActivityStack.IDLE_NOW_MSG; stack.mHandler.sendMessage(msg); } } ...... } } } ...... } 应用程序中的每一个Activity在ActivityManagerService都有一个代表ActivityRecord,它们以堆栈的形式组织在ActivityManaerService中的ActivityStack中。一个即将要显示,但是还没有显示的Activity,它在ActivityManagerService中的ActivityRecord的成员变量nowVisible为false,而成员变量idle为ture,表示这个即将要显示的Activity窗口处于空闲状态。因此,在上面的这个函数中,会执行下面的语句: finalintN=stack.mWaitingVisibleActivities.size(); if(N>0){ for(inti=0;i<N;i++){ ActivityRecordr=(ActivityRecord) stack.mWaitingVisibleActivities.get(i); r.waitingVisible=false; ...... } stack.mWaitingVisibleActivities.clear(); Messagemsg=Message.obtain(); msg.what=ActivityStack.IDLE_NOW_MSG; stack.mHandler.sendMessage(msg); } 前面我们说过,当用户按下键盘上的Back键时,当前激活的Activity记录就被放在ActivityStack对象stack的成员变量mWaitingVisibleActivities中了,这时候就要对它进行处理了。首先是将它们的Activity记录的waitingVisible设置为false,然后就把它们从ActivityStack对象stack的成员变量mWaitingVisibleActivities清空,最后向ActivityStack对象stack发送一个ActivityStack.IDLE_NOW_MSG消息。这个消息最终是由ActivityStack类的activityIdleInternal函数来处理的。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966649,如需转载请自行联系原作者