Android入门之把窗口信息传递给InputDispatcher

        当窗口信息变化时,就应该把变化后的窗口信息传递给InputDispatcher,所以,从“什么时候会改变窗口信息入手”,这些变化的可能有:

        (1) 窗口大小发生变化时;

        (2) 窗口从显示变为隐藏,或隐藏变为显示时;

        (3) 暂停或恢复对消息的处理时;

        (4) 窗口层值发生变化时;

        (5) 添加或删除窗口时;

        这当然只是其中一部分,根据这个思路,在WindowManagerService中寻找对应的方法,柯先生总结有以下方法:

调用updateInputWindowsLw的方法 描述
removeWindowInnerLocked() 删除窗口
relayoutWindow() 重新对窗口进行排级
removeWindowToken() 删除窗口
setTokenVisibilityLocked() 改变窗口的显示状态
InputMonitor.setInputFocusLw() 设置某个窗口为消息输入的对象窗口
InputMonitor.pauseDispatchingLw() 暂停指定窗口接收用户消息
InputMonitor.resumeDispatchingLw() 恢复指定窗口继续接收用户消息
performLayoutLockedInner() 对窗口重新进行排版

        在addWindow分析中说过,添加窗口是调用了performLayoutLockedInner方法实现将信息传递给InputDispatcher的。

        接下来继续分析信息是如何写入InputDispatcher的。

        不难发现,上述方法的共性是都调用了InputMonitor的updateInputWindowLw(),我们主要关注该方法中的以下代码:

mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());

        跟进去,在InputManager中又调用了com_android_server_InputManager.cpp的本地方法:

public void setInputWindows(InputWindow[] windows) {
	nativeSetInputWindows(windows);
}

        nativeSetInputWindows方法代码如下所示:

void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
    Vector windows;

    jsize length = env->GetArrayLength(windowObjArray);
    for (jsize i = 0; i < length; i++) {
        jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
        if (! inputTargetObj) {
            break; // found null element indicating end of used portion of the array
        }

        windows.push();
        InputWindow& window = windows.editTop();
        bool valid = populateWindow(env, inputTargetObj, window);
        if (! valid) {
            windows.pop();
        }

        env->DeleteLocalRef(inputTargetObj);
    }

    mInputManager->getDispatcher()->setInputWindows(windows);
}


        最后的getDispatcher()->setInputWindows顺利把窗口信息传递给了InputDispatcher。

你可能感兴趣的:(Android)