应用程序注销输入事件通道
1.简介
当Activity的窗口创建时,它会向InputManagerService注册输入消息接收通道;而当Activity窗口销毁时,它就会向InputManagerService注销前面注册的输入消息接收通道。
WindowManagerService在处理处于Stopped状态的Activity窗口时,就会注销它们之前所注册的键盘消息接收通道。对于那些处于Stopped状态的Activity窗口来说,它们等待的是销毁,而不是等待可见。所以我们将从ActivityRecord的windowVisiable函数开始分析,输入消息接收通道的注销过程。
2.源码分析
2.1 ActivityRecord.windowsVisible()
final class ActivityRecord {
.....
static class Token extends IApplicationToken.Stub {
@Override
public void windowsVisible() {
synchronized (mService) {
ActivityRecord r = tokenToActivityRecordLocked(this);
if (r != null) {
r.windowsVisibleLocked();//调用ActivityRecord的windowsVisibleLocked(),见2.2
}
}
}
}
}
2.2 ActivityRecord.windowsVisibleLocked()
void windowsVisibleLocked() {
mStackSupervisor.reportActivityVisibleLocked(this);
if (!nowVisible) {
nowVisible = true;
lastVisibleTime = SystemClock.uptimeMillis();
if (!idle) {
mStackSupervisor.processStoppingActivitiesLocked(false);
} else {
final int size = mStackSupervisor.mWaitingVisibleActivities.size();//等待可见的Activity
if (size > 0) {
for (int i = 0; i < size; i++) {
ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);//获取ActivityRecord记录
}
mStackSupervisor.mWaitingVisibleActivities.clear();
mStackSupervisor.scheduleIdleLocked();//调用ActivityStackSupervisor的scheduleIdleLocked()方法,见2.3
}
}
service.scheduleAppGcsLocked();
}
}
......
}
应用程序中的每一个Activity在ActivityManagerService中都有一个ActivityRecord对应,它们是以堆栈的形式组织在ActivityManagerService中的ActivityStack中。一个即将要显示,但还没有显示的Activity,它的ActivityRecord的成员变量nowVisible为false,成员变量idle为true,表示这个即将要显示的Activity窗口处于空闲状态。
2.3 ActivityStackSupervisor.scheduleIdleLocked()
final void scheduleIdleLocked() {
mHandler.sendEmptyMessage(IDLE_NOW_MSG);//发送IDLE_NOW_MSG消息,最终调用activityIdleInternal()方法,见2.4
}
2.4 ActivityStackSupervisor.activityIdleInternalLocked()
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
.....
final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(true);
NS = stops != null ? stops.size() : 0;
.....
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.task.stack;
if (stack != null) {
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);//调用ActivityStack的finishCurrentActivityLocked()方法,见2.5
} else {
stack.stopActivityLocked(r);//调用ActivityStack的stopActivityLocked方法
}
}
}
.....
}
如果ActivityRecord的finishing变量为true的话,将调用ActivityStack的finishCurrentActivityLocked()方法来销毁Activity。
2.5 ActivityStack.finishCurrentActivityLocked()
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
.....
mStackSupervisor.mStoppingActivities.remove(r);
mStackSupervisor.mGoingToSleepActivities.remove(r);
mStackSupervisor.mWaitingVisibleActivities.remove(r);
......
final ActivityState prevState = r.state;
r.state = ActivityState.FINISHING;
if (mode == FINISH_IMMEDIATELY
|| (prevState == ActivityState.PAUSED
&& (mode == FINISH_AFTER_PAUSE || mStackId == PINNED_STACK_ID))
|| finishingActivityInNonFocusedStack
|| prevState == ActivityState.STOPPED
|| prevState == ActivityState.INITIALIZING) {
r.makeFinishingLocked();
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");//销毁Activity,见2.6
.....
}else{
.......
}
return r;
}
如果传进来的mode为FINISH_IMMEDIATELY,并且Activity的状态为Stopped,则销毁该Activity。
2.6 ActivityStack.destroyActivityLocked()
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
r.userId, System.identityHashCode(r),